• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Cryptosystem] RSA

JASS:
library RSA /* v1.0
************************************************************
*
*    RSA Cryptosystem
*
*	 --------------------
*
*		A Cryptosystem that uses the Euler's totient function
*       in encrypting/decrypting numbers
*
*
************************************************************
*
*    API
*
*	static method create takes player temp returns thistype
*		- generates RSA keys for player "temp"
*
*	method encrypt takes thistype p, integer m returns integer
*		- encrypts a number by using "p" key
*
*	method decrypt takes integer m returns integer
*		- decrypts an encrypted number
*
************************************************************/

	globals
		private constant integer MIN_KEY = 1024
		private constant integer MAX_KEY = 8192
		
		private constant boolean USE_PHI = false
	endglobals
	
	struct RSA extends array
		
		private integer pbKey
		private integer pvKey
		private integer p
		private integer q
		private integer n
		private integer f
		private integer e
		private integer d
		
		private player owner
		private static boolean array primes
		
		/************************************************************
		*
		*    Math libraries for encryption/decryption
		*
		************************************************************/
		private static method mod takes integer a, integer b returns integer
			return ModuloInteger(a, b)
		endmethod
		
		private static method isPrime takes integer i returns boolean
			local integer a
			local integer c = 1
			if primes[i] == null then
				if mod(i, 1) != 0 and i<2 then
					return false
				endif
				set a = R2I(SquareRoot(I2R(i)))
				loop
					if mod(i, c) == 0 then
						return false
					endif
					exitwhen c == a
					set c = c + 1
				endloop
				set primes[i] = true
				return true
			endif
			return true
		endmethod
		
		private static method gcd takes integer a, integer b returns integer
			local integer i = 0
			if b != 0 then
				loop
					set i = a
					set a = b
					set b = mod(i, b)
					if b == 0 then
						return a
					endif
				endloop
			endif
			return a
		endmethod
		
		private static method lcm takes integer a, integer b returns integer
			return a*b/gcd(a, b)
		endmethod
		
		private static method isCoprime takes integer a, integer b returns boolean
			return gcd(a, b) == 1
		endmethod
		
		private static method totient takes integer n returns integer
			local integer count = 0
			local integer i = 1
			loop
				if coprime(i, n) then
					set count = count + 1
				endif
				exitwhen i == n
			endloop
			return count
		endmethod
		
		private static method randomPrime takes nothing returns integer
			local integer pr
			loop
				set pr = RandomInt(MIN_KEY, MAX_KEY)
				if isPrime(pr) then
					return pr
				endif
			endloop
		endmethod
		
		private static method randomCoprime takes integer max returns integer
			local integer c
			loop
				set c = RandomInt(2, max - 1)
				if isCoprime(c, max) then
					return c
				endif
			endloop
		endmethod
		/************************************************************
		*
		*    Main functions/methods
		*
		************************************************************/
		
		static method create takes player temp returns thistype
			local thistype this = thistype(GetPlayerId(temp))
			set owner = temp
			set p = randomPrime()
			set q = randomPrime()
			set n = p*q
			if USE_PHI then
				set f = totient(n)
			else
				set f = lcm(p - 1, q - 1)
			endif
			set e = randomCoprime(f)
			set d = R2I(ModuloReal(1/I2R(e), I2R(f))
			
			set pbKey = e
			set pvKey = d
			
			return this
		endmethod
		
		method encrypt takes thistype p, integer m returns integer
			return mod(R2I(Pow(I2R(m), I2R(p.pbKey))), p.n)
		endmethod
		
		method decrypt takes integer m returns integer
			return mod(R2I(Pow(I2R(m), I2R(pvKey))), n)
		endmethod
	endstruct
endlibrary

Example:
JASS:
struct Tester extends array
    private static method onInit takes nothing returns nothing
        local integer i = RSA.create(Player(0))
        local integer t = RSA.create(Player(1))

        // "Send" 1000 to "t" from "i"
        local integer m =  i.encrypt(t, 1000)

        // Decrypt message from "i"
        call BJDebugMsg(I2S(t.decrypt(m)))
    endmethod
endstruct
 
Last edited:
Here's a version that compiles (there were many errors), however I'm not sure if it's functional.

JASS:
library RSA /* v1.0
************************************************************
*
*    RSA Cryptosystem
*
*    --------------------
*
*       A Cryptosystem that uses the Euler's totient function
*       in encrypting/decrypting numbers
*
*
************************************************************
*
*    API
*
*   static method create takes player temp returns thistype
*       - generates RSA keys for player "temp"
*
*   method encrypt takes thistype p, integer m returns integer
*       - encrypts a number by using "p" key
*
*   method decrypt takes integer m returns integer
*       - decrypts an encrypted number
*
************************************************************/

    globals
        private constant integer MIN_KEY = 1024
        private constant integer MAX_KEY = 8192
        
        private constant boolean USE_PHI = false
    endglobals
    
    struct RSA extends array
        
        private integer pbKey
        private integer pvKey
        private integer p
        private integer q
        private integer n
        private integer f
        private integer e
        private integer d
        
        private player owner
        private static boolean array primes
        
        /************************************************************
        *
        *    Math libraries for encryption/decryption
        *
        ************************************************************/
        private static method mod takes integer a, integer b returns integer
            return ModuloInteger(a, b)
        endmethod
        
        private static method isPrime takes integer i returns boolean
            local integer a
            local integer c = 1
            if not primes[i] then
                if mod(i, 1) != 0 and i<2 then
                    return false
                endif
                set a = R2I(SquareRoot(I2R(i)))
                loop
                    if mod(i, c) == 0 then
                        return false
                    endif
                    exitwhen c == a
                    set c = c + 1
                endloop
                set primes[i] = true
                return true
            endif
            return true
        endmethod
        
        private static method gcd takes integer a, integer b returns integer
            local integer i = 0
            if b != 0 then
                loop
                    set i = a
                    set a = b
                    set b = mod(i, b)
                    if b == 0 then
                        return a
                    endif
                endloop
            endif
            return a
        endmethod
        
        private static method lcm takes integer a, integer b returns integer
            return a*b/gcd(a, b)
        endmethod
        
        private static method isCoprime takes integer a, integer b returns boolean
            return gcd(a, b) == 1
        endmethod
        
        private static method totient takes integer n returns integer
            local integer count = 0
            local integer i = 1
            loop
                if isCoprime(i, n) then
                    set count = count + 1
                endif
                exitwhen i == n
            endloop
            return count
        endmethod
        
        private static method randomPrime takes nothing returns integer
            local integer pr
            loop
                set pr = GetRandomInt(MIN_KEY, MAX_KEY)
                if isPrime(pr) then
                    return pr
                endif
            endloop
            return 0
        endmethod
        
        private static method randomCoprime takes integer max returns integer
            local integer c
            loop
                set c = GetRandomInt(2, max - 1)
                if isCoprime(c, max) then
                    return c
                endif
            endloop
            return 0
        endmethod
        /************************************************************
        *
        *    Main functions/methods
        *
        ************************************************************/
        
        static method create takes player temp returns thistype
            local thistype this = thistype(GetPlayerId(temp))
            local integer tq
            local integer tp
            local real tf
            
            set owner = temp
            set p = randomPrime()
            set q = randomPrime()
            set n = R2I(tp*tq)
            
            static if USE_PHI then
                set tf = totient(n)
            else
                set tf = lcm(tp - 1, tq - 1)
            endif
            set e = randomCoprime(f)
            set d = R2I(ModuloReal(1/I2R(e), I2R(f)))
            
            set pbKey = e
            set pvKey = d
            
            return this
        endmethod
        
        method encrypt takes thistype p, integer m returns integer
            return mod(R2I(Pow(I2R(m), I2R(p.pbKey))), p.n)
        endmethod
        
        method decrypt takes integer m returns integer
            return mod(R2I(Pow(I2R(m), I2R(pvKey))), n)
        endmethod
    endstruct
endlibrary

I also used a static if for USE_PHI.
 
Level 14
Joined
Jun 27, 2008
Messages
1,325
what is this for?

Also why use a non-static method and pass the object via argument? (As far as i can see the function doesnt use the this-pointer)
JASS:
*   method encrypt takes thistype p, integer m returns integer
*       - encrypts a number by using "p" key
Either use a function / static method and pass the object via argument or use a non-static method and refer to the object using "this" (the latter is usually the prefered solution).
 
Last edited:
Level 14
Joined
Jun 27, 2008
Messages
1,325
And pls more typesafety, this is awful to read :S
JASS:
local integer i = RSA.create(Player(0))

Agree, and the example
JASS:
        local integer i = RSA.create(Player(0))

        // "Send" 1000 to "t" from "i"
        local integer m =  i.encrypt(t, 1000)
shouldnt even compile as you need to cast i to the struct type before you can invoke a method.


And by the way, this is the Submissions-forum. Stuff that isnt even checked for compile errors shouldnt be posted here.
 
Level 23
Joined
Jan 1, 2009
Messages
1,610
Are you running solaris or what?
Even with wine JH perfectly works so that excuse it not viable.

Anyways this has practical no use.
Even with S/L libraries, the easiest way to just "hack" yourself into them is not modifying the save, but just adding code to the war3map.j that e.g. let's you set values and spawn stuff.

Therefore these kinds of cryptics are just meaningless in the wc3 enviroment.
Making the Code not readable by normal players is useful, but a simple change of base does that for you AND compresses the code.
 

LeP

LeP

Level 13
Joined
Feb 13, 2008
Messages
539
Just graveyard this shit.
Im tired of Wc3 modding.

there are better reasons to graveyard this than you going inactive.
one should look for public-key systems with much smaller key length to implement in wc3.
 
Level 14
Joined
Jun 27, 2008
Messages
1,325
Unless you are trying to run it on a smartphone or tablet i dont see a reason why you shouldnt be able to run JassHelper. It works on all the big platforms.

And if ur tired of vjass just use Wurst, which should also solve your compiler problem as it runs almost everywhere.
 
Top