My Cats implement Diffie Hellman in Powershell
December 20, 2022My two cats use Diffie Hellman to exchange keys
How else would they plan to overthrow me without being spied on?
Usual disclaimer. This is a demo and not actual cryptographyically secure
First both these boys agreed on a constant. Because we have a large hex string, we need a special function to assign it. They are using standardised numbers, consider them agreed in advance, and not secret.
> $p = [System.Numerics.BigInteger]::Parse("ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff", 'AllowHexSpecifier')
> $g = 2
Slinky will go first generating his keys using the secure method of walking on a keyboard while I’m typing.
PS > $secretA = 45657345
PS > $pubA = [BigInt]::ModPow($g, $secretA, $p)
PS > $pubA
13609600351875569882809616896881123276087718251643663793280292733084627951726136615250320518264146504736625497843535440631016741414051317517237855044495278160880258571039365920113687240473506701607125293759819578278125996455961534449398173645850946944357573866230663628068618345230180820355142961294257831068839984340244606907609231092919599161335614190704096004849031225149028756239988489757888240356552236473585327023203069779216589046628779
Now Winston will generate his keys. Because he’s going second, he can calculate the shared key.
PS > $secretB = 12324242
PS > $pubB = [BigInt]::ModPow($g, $secretB, $p)
PS > $pubB
6753888779355890139400341882241333603447303360691444785369413104817527915632460520087350069191964693836314319152317725307683961781128239982138111877109907732975299936917908890763197037491520233975772367888223902332565405676859846836304286178803886413657453979872364417446753816557683737197018038986771921027338799345906627138416649345374066504459255948445480849807624990340869839677106295656649225509655893613019898674957948149591530191250551
PS > $shared = [BigInt]::ModPow([BigInt]::Parse('13609600351875569882809616896881123276087718251643663793280292733084627951726136615250320518264146504736625497843535440631016741414051317517237855044495278160880258571039365920113687240473506701607125293759819578278125996455961534449398173645850946944357573866230663628068618345230180820355142961294257831068839984340244606907609231092919599161335614190704096004849031225149028756239988489757888240356552236473585327023203069779216589046628779'), $secretB, $p)
Back to slinky, he can use the public key Winston now gave him to calculate the secret.
PS > $shared2 = [BigInt]::ModPow([BigInt]::Parse('6753888779355890139400341882241333603447303360691444785369413104817527915632460520087350069191964693836314319152317725307683961781128239982138111877109907732975299936917908890763197037491520233975772367888223902332565405676859846836304286178803886413657453979872364417446753816557683737197018038986771921027338799345906627138416649345374066504459255948445480849807624990340869839677106295656649225509655893613019898674957948149591530191250551'), $secretA, $p)
And now despite neither of them telling me what the shared secret is, they both know it.
PS > $shared -eq $shared2
True
Of course you need a way to turn a big number into a key.
PS > $sha = [System.Security.Cryptography.HashAlgorithm]::Create('sha256')
PS > $hash = $sha.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($shared))
PS > [System.BitConverter]::ToString($hash) -replace '-'
FF76E1BCD82D50612DDAB91BB07F58DDAEC9287BEA9ABC2E863059D78E584A95