Last active
December 5, 2023 19:19
-
-
Save Zenithar/2e81cb7e122d0ff38adbd9971c3c939b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"crypto/ecdh" | |
"crypto/rand" | |
"crypto/sha256" | |
"fmt" | |
"io" | |
"os" | |
"github.com/cloudflare/circl/kem/kyber/kyber768" | |
"golang.org/x/crypto/hkdf" | |
) | |
// This snippet implements X25519+Kyber768 key exchange. | |
// https://www.ietf.org/archive/id/draft-tls-westerbaan-xyber768d00-02.html | |
func main() { | |
// X25518 ECDH | |
xc := ecdh.X25519() | |
// Kyber768 KEM | |
k := kyber768.Scheme() | |
// Client ------------------------------------------------------------------ | |
// Generate private key | |
xskC, err := xc.GenerateKey(rand.Reader) | |
if err != nil { | |
panic(err) | |
} | |
xpkC := xskC.PublicKey() | |
kpkC, kskC, err := k.GenerateKeyPair() | |
if err != nil { | |
panic(err) | |
} | |
bkpkC, _ := kpkC.MarshalBinary() | |
fmt.Fprintf(os.Stdout, "Client => Server: xpkC (%x) || kpkC (%x)\n", xpkC.Bytes(), bkpkC) | |
// Server ------------------------------------------------------------------ | |
// Generate private key | |
xskS, err := xc.GenerateKey(rand.Reader) | |
if err != nil { | |
panic(err) | |
} | |
xpkS := xskS.PublicKey() | |
// Generate random secret matching the encapsulated seed size. | |
randomSecret := make([]byte, k.EncapsulationSeedSize()) | |
if _, err := io.ReadFull(rand.Reader, randomSecret[:]); err != nil { | |
panic(err) | |
} | |
// Encapsulate the random secret using the client kyber public key. | |
encS, ssS, err := k.EncapsulateDeterministically(kpkC, randomSecret) | |
if err != nil { | |
panic(err) | |
} | |
// Compute xpkC^xskS | |
xssS, err := xskS.ECDH(xpkC) | |
if err != nil { | |
panic(err) | |
} | |
// HKDF-SHA256(xssS || ssS) for final shared secret derivation. | |
sharedSecretS := hkdf.Extract(sha256.New, append(xssS, ssS...), nil) | |
fmt.Fprintf(os.Stdout, "Server => Client: xpkS (%x) || encS (%x)\n", xpkS.Bytes(), encS) | |
// Client ------------------------------------------------------------------ | |
xssC, err := xskC.ECDH(xpkS) | |
if err != nil { | |
panic(err) | |
} | |
ssC, err := k.Decapsulate(kskC, encS) | |
if err != nil { | |
panic(err) | |
} | |
sharedSecretC := hkdf.Extract(sha256.New, append(xssC, ssC...), nil) | |
// ------------------------------------------------------------------------- | |
fmt.Fprintf(os.Stdout, "SharedSecret (S) %x\n", sharedSecretS) | |
fmt.Fprintf(os.Stdout, "SharedSecret (C) %x\n", sharedSecretC) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Client => Server: xpkC (ff3e2fd4e76815edacc0459458ed9de85dc8c14454905c5d9e42ee16f4c0264e) || kpkC (e756581efca29d532d6f5c3b5efc5b8ee9a6f26aa2cae520a71acc19b668296196aab0b92cdb3b1f9705159494b23816c24502253313517131432ca48c10902b7588e1a41c8e1a9b2725cf5a48b0e1c750d6ec451b0b63f9ec8c147a39052bc9990cc94b04b275a469c592c2a81a2a3ad7c012b0c0b75669d26ac112654c94db16f49645430099b93337f42a91b946373443760854c7dd01699d43559da92b4f860ca2302b44ba7a3f7a202313438586cab3e804809792a80626b94906ef68344d8a8c5f05079545b6fac246c8eaa252196721193eb1a71eb6c89d5c458eaab984852267ec808df6829da1612ae9d132dd501c11f3247eea40f7597a590b42235a6bf840b365d93d20041671c67f44e3a65a43cb61577caed59929fa4fe9065a7a9c2655c2afb34abeac6625a4609d683ac10e6564c1ca6562078721e93f06f6378978676b52a026288c56e1b52398c5f5429587a1301c9c0afe952c0f29104f5b58c18186adb971e6e65314287b09969c57cc864afa642e86a818139883b127cae6c5907b3a283195a3314988da347c626ecfe9b807a1cacb507484710d10678ba5a606838688ed783a91547644aa261499ac72c35d3e4cbe70e28decca4551f37b8156668fa869248a0575e78529524e137b440d1849adca835227a99e683892071adcd38a442cc1ea57b43a426470b9bfbf8659a6a999f6972f70b02e5de338038323735081def034373c0a2145b13ffbb46205382e172473c34801f0639cd07596d85c854969eff572f4416d5f721c78b58bbe64393eb302cddc34abdbb6379ac7d125a32441304894a40a16ad9fd4a80d604ff03a26b5772b439505b3a3ae07f8279564551a73c7520b44e8da14766c7940ec12e143824efc1f1abb86904890a5234a72d96045eb620b115ffe67b3a762bf3b514d7ebcafed572a4d398d5eca446cc645d3f281b569545b876dd5e952f610583dc1a474da6e2c76ba7fc24ae7a70c8c262f8f1807296c49d2d6c6877bc279e2c0d285797c44b5b7001d81db2cd52c20cb97ccdfb0101da837feda0148f3be16f35271655c624460a2d7491d4757f6161b7c7513c92986f6847cacd7832c6113ba741b23a0c923eb1aac3377a6e64d4fa97b063806d286a9185bae60526f8666921778872bb2bd06434a66c2a83d1a3570f75b25c869d304a89494884311c62bc11123e78d028660ecf06bafd56b78391ec8f54525ba9794d23d0c909b47285b5960a393f9751e4b0ecb002dfbfaa3334c936dcb99d92c090ea680ad81984f003f4110a920528f39102a348237b47513433794e813112ba466ab770780d9074b90420200284b48c12f3741e8568aa2516021d9bcd8c8a572e1822efa37049b62f6192b76171af615150da302b0d38b12326226636499b9cee0fb51b9d25ac882ae12945877022f825064700209bd71693732ac4216cb1301584cb948040c683088131dabb6a6094a68b4a45d691474a5394745af376331c361c4d319bab48359d6a393940468d9a0351f3cca963042a8b746620a61d35a73c3b117ea4476313a4e48a53815c45ff331c5d7f54cc17b59cd0a901c1a85c5c2a88503af2fcca62cea50ca671a2de25be94b4319f2ad48698ff1556b30dae138a5b6ffa8eb7b59d9d6b52cbbedf2dcf40d2475) | |
Server => Client: xpkS (9f56bd72e36ddbbd2e4534e2d04da595ee68d7b8bfc39a130dc28ed683bf9f45) || encS (ee080605def092acf2401b7edead7f693d896c49717a26b26861f312d514a8d4b373b59167c86abb993b521444c059918ada88df9e9b3bea83786edce0cfdaf2f64e5c3205d86d90c022a71c2f5f88913106d8aa017cb4318952573cbb8d4fce4a1ef495b376f528f69bc4d181e643d69c1311bcabcd9635ee45da0b92b1aa5e1c47b5eec814a6b50f7e1e7d6f00394014bbdaf411809599cf03e55acc05bace24b5c3c67e4e7e9d876a2df85f4f1dbbca6dfd15357508312daa75a11b7197eeffc9910d03acf734c3bf84506a922e655560493ab601d1cf69550a6d1a8480bc52ce0c84314bf09854dcaa92c95f66fdbc8e1aff5c7c8faa1c4c4e8687fa4c6014a655edcd85430012d439cba9cd3d5c0878c1e928db8b1abb5ce97c0d4096c414dd24c7bc47bd40a8bd3867a5624075f80c97125b2d8a0b0b98671ee0d9de59da63b6025be8d759d2bb61e2af082966e84110d512e18407e95b028337f7d0258a01281a1b8bb6db4a385c8c1a760395f155fae9b3d256782e7fc3074cc0571d7cd17d9c7e21e0041886ede3bdfaa53479d5745201c2d6fb653c00bdaf0a01e48531cb266651c0ddc9a03f737a35900fe0135226a3ee3cf3d714a9159822e8f07909cdd5183f8541fead3cd66ceb55d1a7b158ddbff8daaeac054bf27d4c517876dd4c270ac606a2dc4ed0f6b0129cde377f3f77e97f6ffe454ecf37759b7e165f7d700eb0be98db65530fdbf93bfad51f663351e2f85c0c6dc132ba5c11ed0418e1c8f2e33b5e5434a33c1deb980fe38964ae0a92b6c24775df1d1341672a90bd320199db809f3b3a04a50be8246e8432d7b8be230502b0de389881e101d7e30e3398e1b83282e7b744621198b644e511695f9f09f4ed0770457f4cdeae567d59457207072c8a2699f4435e6b913ef1bcf8f726b7e5fbd1a633a42ddb2a4782f11e916ef6f156a569c9799779df796157734767e5c19c357758fd81bec41b589ed2cc4100e542028da294a308ac7b4581a3367e5f547d4ba96e8fd23479f8648329c6f4902c585b3b40e6244cb295cd083844dcf46e82e963f71c4df19ecea002b4759ee028c525b7d1549ac302030b889b25b8ceb5c87829f00942d558cf7d8d95d346a65cef817c35e1f260ab4f79e0772d2dd899218d34f845415f61b1b51a1b7fd57ada43563cf2caf216eafa4246851f9b600de903936c05a7b7e7c6fa89fb7a683cd8c38322a4f79ab4a7157099b2c67b330798b728950d8077a02b4ec44088f6bd4625c24144dee2956fc84910858684a58c0c9def294160268bc8900fd4ea6ce5975dbd8e7b7c97313f2d07d4bbdf798c876fd23f13dcdd17dc4c4d80efe81f7052d7295e2dde25d4c411a2fbdb0e88f8efa01b257ac7978bacd19feb8b3f53a5891978b75ff3018e636b6efb0e873aa2bd444b85f736755f7c3b686e08cbd5ce9df0599bbb30fdd6fce5c007e4c2f0ef73c99774a213a8fd2a9f3eb68cf3c3a1710269b21bfc77f3ad3ba0eefc719fd09b57556fba8210823043dc) | |
SharedSecret (S) d9d0c51b012d4677ebbc58e9b14ee4357cbde8c97d2c354c50a7cc973fd9206b | |
SharedSecret (C) d9d0c51b012d4677ebbc58e9b14ee4357cbde8c97d2c354c50a7cc973fd9206b |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment