├── .gitignore ├── go.mod ├── binding1024.h ├── binding2048.h ├── binding511.h ├── binding512.h ├── AUTHORS.md ├── blinding_test.go ├── go.sum ├── binding_bench_test.go ├── .gitlab-ci.yml ├── binding_test.go ├── README.md ├── vectors511_test.go ├── vectors512_test.go ├── vectors1024_test.go ├── vectors2048_test.go ├── binding.go └── autogen-memoized.patch /.gitignore: -------------------------------------------------------------------------------- 1 | high-ctidh-* 2 | *~ 3 | binding.h -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module git.xx.network/elixxir/ctidh_cgo 2 | 3 | go 1.16 4 | 5 | require github.com/stretchr/testify v1.8.0 6 | -------------------------------------------------------------------------------- /binding1024.h: -------------------------------------------------------------------------------- 1 | #ifndef _BINDING_H 2 | #define _BINDING_H 3 | 4 | #define NAMESPACEBITS(x) highctidh_1024_##x 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /binding2048.h: -------------------------------------------------------------------------------- 1 | #ifndef _BINDING_H 2 | #define _BINDING_H 3 | 4 | #define NAMESPACEBITS(x) highctidh_2048_##x 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /binding511.h: -------------------------------------------------------------------------------- 1 | #ifndef _BINDING_H 2 | #define _BINDING_H 3 | 4 | #define NAMESPACEBITS(x) highctidh_511_##x 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /binding512.h: -------------------------------------------------------------------------------- 1 | #ifndef _BINDING_H 2 | #define _BINDING_H 3 | 4 | #define NAMESPACEBITS(x) highctidh_512_##x 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | Public domain. 2 | 3 | Authors of the CGO Go bindings to CTIDH: 4 | 5 | * David A. Stainton 6 | 7 | 8 | autogen-memoized.patch written by Jacob Appelbaum with assistance from Daniel Bernstein. 9 | 10 | -------------------------------------------------------------------------------- /blinding_test.go: -------------------------------------------------------------------------------- 1 | package ctidh 2 | 3 | import ( 4 | "crypto/rand" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestSimpleBlindingOperation(t *testing.T) { 11 | _, alicePublic := GenerateKeyPair() 12 | 13 | blindingFactor := make([]byte, PrivateKeySize) 14 | _, err := rand.Read(blindingFactor) 15 | require.NoError(t, err) 16 | 17 | oldKey := alicePublic.Bytes() 18 | err = alicePublic.Blind(blindingFactor) 19 | require.NoError(t, err) 20 | newKey := alicePublic.Bytes() 21 | 22 | require.NotEqual(t, oldKey, newKey) 23 | require.Equal(t, len(oldKey), len(newKey)) 24 | } 25 | 26 | func TestBlindingOperation(t *testing.T) { 27 | mixPrivateKey, mixPublicKey := GenerateKeyPair() 28 | clientPrivateKey, clientPublicKey := GenerateKeyPair() 29 | 30 | blindingFactor := make([]byte, PrivateKeySize) 31 | _, err := rand.Read(blindingFactor) 32 | require.NoError(t, err) 33 | 34 | value1, err := Blind(blindingFactor, NewPublicKey(DeriveSecret(clientPrivateKey, mixPublicKey))) 35 | require.NoError(t, err) 36 | blinded, err := Blind(blindingFactor, clientPublicKey) 37 | require.NoError(t, err) 38 | value2 := DeriveSecret(mixPrivateKey, blinded) 39 | 40 | require.Equal(t, value1.Bytes(), value2) 41 | } 42 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 5 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 6 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 7 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 8 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 9 | github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= 10 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 11 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 12 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 13 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 14 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 15 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 16 | -------------------------------------------------------------------------------- /binding_bench_test.go: -------------------------------------------------------------------------------- 1 | package ctidh 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func BenchmarkPublicKeySerializing(b *testing.B) { 10 | for n := 0; n < b.N; n++ { 11 | privKey, publicKey := GenerateKeyPair() 12 | 13 | publicKeyBytes := publicKey.Bytes() 14 | 15 | publicKey2 := new(PublicKey) 16 | err := publicKey2.FromBytes(publicKeyBytes) 17 | require.NoError(b, err) 18 | 19 | publicKey2Bytes := publicKey2.Bytes() 20 | publicKey3 := DerivePublicKey(privKey) 21 | publicKey3Bytes := publicKey3.Bytes() 22 | 23 | require.Equal(b, publicKeyBytes, publicKey2Bytes) 24 | require.Equal(b, publicKey3Bytes, publicKeyBytes) 25 | } 26 | } 27 | 28 | func BenchmarkPrivateKeySerializing(b *testing.B) { 29 | for n := 0; n < b.N; n++ { 30 | privateKey, _ := GenerateKeyPair() 31 | privateKeyBytes := privateKey.Bytes() 32 | 33 | privateKey2 := new(PrivateKey) 34 | privateKey2.FromBytes(privateKeyBytes) 35 | privateKey2Bytes := privateKey2.Bytes() 36 | 37 | require.Equal(b, privateKeyBytes, privateKey2Bytes) 38 | } 39 | } 40 | 41 | func BenchmarkNIKE(b *testing.B) { 42 | for n := 0; n < b.N; n++ { 43 | alicePrivate, alicePublic := GenerateKeyPair() 44 | bobPrivate, bobPublic := GenerateKeyPair() 45 | 46 | bobSharedBytes := DeriveSecret(bobPrivate, alicePublic) 47 | aliceSharedBytes := DeriveSecret(alicePrivate, bobPublic) 48 | 49 | require.Equal(b, bobSharedBytes, aliceSharedBytes) 50 | } 51 | } 52 | 53 | func BenchmarkDeriveSecret(b *testing.B) { 54 | alicePrivate, alicePublic := GenerateKeyPair() 55 | bobPrivate, bobPublic := GenerateKeyPair() 56 | 57 | var aliceSharedBytes []byte 58 | for n := 0; n < b.N; n++ { 59 | aliceSharedBytes = DeriveSecret(alicePrivate, bobPublic) 60 | } 61 | 62 | bobSharedBytes := DeriveSecret(bobPrivate, alicePublic) 63 | require.Equal(b, bobSharedBytes, aliceSharedBytes) 64 | } 65 | 66 | func BenchmarkGenerateKeyPair(b *testing.B) { 67 | for n := 0; n < b.N; n++ { 68 | _, _ = GenerateKeyPair() 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | before_script: 2 | - go version || echo "Go executable not found." 3 | - echo $CI_BUILD_REF 4 | - echo $CI_PROJECT_DIR 5 | - echo $PWD 6 | - eval $(ssh-agent -s) 7 | - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null 8 | - mkdir -p ~/.ssh 9 | - chmod 700 ~/.ssh 10 | - ssh-keyscan -t rsa $GITLAB_SERVER > ~/.ssh/known_hosts 11 | - rm -rf ~/.gitconfig 12 | - git config --global url."git@$GITLAB_SERVER:".insteadOf "https://gitlab.com/" 13 | - git config --global url."git@$GITLAB_SERVER:".insteadOf "https://git.xx.network/" --add 14 | - export PATH=$HOME/go/bin:$PATH 15 | 16 | stages: 17 | - test 18 | 19 | test: 20 | stage: test 21 | image: $DOCKER_IMAGE 22 | except: 23 | - tags 24 | script: 25 | - git clean -ffdx 26 | - mkdir high-ctidh 27 | - cd high-ctidh 28 | - 'wget -O high-ctidh.zip --header="PRIVATE-TOKEN: $GITLAB_ACCESS_TOKEN" "https://$GITLAB_SERVER/api/v4/projects/elixxir%2Fhigh-ctidh/jobs/artifacts/master/download?job=build"' 29 | - unzip high-ctidh.zip 30 | - export P=`pwd` 31 | - cd .. 32 | # 511 33 | - cp binding511.h binding.h 34 | - export CTIDH_BITS=511 35 | - export CGO_CFLAGS="-g -I${P} -DBITS=${CTIDH_BITS}" 36 | - export CGO_LDFLAGS="-L${P} -Wl,-rpath,${P} -lhighctidh_${CTIDH_BITS}" 37 | - go test -v -bench . 38 | # 512 39 | - cp binding512.h binding.h 40 | - export CTIDH_BITS=512 41 | - export CGO_CFLAGS="-g -I${P} -DBITS=${CTIDH_BITS}" 42 | - export CGO_LDFLAGS="-L${P} -Wl,-rpath,${P} -lhighctidh_${CTIDH_BITS}" 43 | - go test -v -bench . 44 | # 1024 45 | - cp binding1024.h binding.h 46 | - export CTIDH_BITS=1024 47 | - export CGO_CFLAGS="-g -I${P} -DBITS=${CTIDH_BITS}" 48 | - export CGO_LDFLAGS="-L${P} -Wl,-rpath,${P} -lhighctidh_${CTIDH_BITS}" 49 | - go test -v -bench . 50 | # 2048 51 | - cp binding2048.h binding.h 52 | - export CTIDH_BITS=2048 53 | - export CGO_CFLAGS="-g -I${P} -DBITS=${CTIDH_BITS}" 54 | - export CGO_LDFLAGS="-L${P} -Wl,-rpath,${P} -lhighctidh_${CTIDH_BITS}" 55 | - go test -v -bench . 56 | -------------------------------------------------------------------------------- /binding_test.go: -------------------------------------------------------------------------------- 1 | package ctidh 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func TestPrivateKeyPEMSerialization(t *testing.T) { 12 | privateKey, _ := GenerateKeyPair() 13 | 14 | tmpdir := os.TempDir() 15 | 16 | privateKeyPemFile := "private_key.pem" 17 | pemFile := filepath.Join(tmpdir, privateKeyPemFile) 18 | err := privateKey.ToPEMFile(pemFile) 19 | require.NoError(t, err) 20 | 21 | privateKey2 := NewEmptyPrivateKey() 22 | err = privateKey2.FromPEMFile(pemFile) 23 | require.NoError(t, err) 24 | 25 | require.Equal(t, privateKey.Bytes(), privateKey2.Bytes()) 26 | } 27 | 28 | func TestPublicKeyPEMSerialization(t *testing.T) { 29 | _, publicKey := GenerateKeyPair() 30 | 31 | tmpdir := os.TempDir() 32 | 33 | publicKeyPemFile := "public_key.pem" 34 | pemFile := filepath.Join(tmpdir, publicKeyPemFile) 35 | err := publicKey.ToPEMFile(pemFile) 36 | require.NoError(t, err) 37 | 38 | publicKey2 := NewEmptyPublicKey() 39 | err = publicKey2.FromPEMFile(pemFile) 40 | require.NoError(t, err) 41 | 42 | require.Equal(t, publicKey.Bytes(), publicKey2.Bytes()) 43 | } 44 | 45 | func TestPublicKeyReset(t *testing.T) { 46 | zeros := make([]byte, PublicKeySize) 47 | _, publicKey := GenerateKeyPair() 48 | require.NotEqual(t, publicKey.Bytes(), zeros) 49 | 50 | publicKey.Reset() 51 | require.Equal(t, publicKey.Bytes(), zeros) 52 | } 53 | 54 | func TestPrivateKeyReset(t *testing.T) { 55 | zeros := make([]byte, PrivateKeySize) 56 | privateKey, _ := GenerateKeyPair() 57 | require.NotEqual(t, privateKey.Bytes(), zeros) 58 | 59 | privateKey.Reset() 60 | require.Equal(t, privateKey.Bytes(), zeros) 61 | } 62 | 63 | func TestPublicKeyMarshaling(t *testing.T) { 64 | privKey, publicKey := GenerateKeyPair() 65 | publicKeyBytes := publicKey.Bytes() 66 | 67 | publicKey2 := new(PublicKey) 68 | err := publicKey2.FromBytes(publicKeyBytes) 69 | require.NoError(t, err) 70 | 71 | publicKey2Bytes := publicKey2.Bytes() 72 | 73 | publicKey3 := DerivePublicKey(privKey) 74 | publicKey3Bytes := publicKey3.Bytes() 75 | 76 | require.Equal(t, publicKeyBytes, publicKey2Bytes) 77 | require.Equal(t, publicKey3Bytes, publicKeyBytes) 78 | } 79 | 80 | func TestPrivateKeyBytesing(t *testing.T) { 81 | privateKey, _ := GenerateKeyPair() 82 | privateKeyBytes := privateKey.Bytes() 83 | 84 | privateKey2 := new(PrivateKey) 85 | privateKey2.FromBytes(privateKeyBytes) 86 | privateKey2Bytes := privateKey2.Bytes() 87 | 88 | require.Equal(t, privateKeyBytes, privateKey2Bytes) 89 | } 90 | 91 | func TestNIKE(t *testing.T) { 92 | alicePrivate, alicePublic := GenerateKeyPair() 93 | bobPrivate, bobPublic := GenerateKeyPair() 94 | bobSharedBytes := DeriveSecret(bobPrivate, alicePublic) 95 | aliceSharedBytes := DeriveSecret(alicePrivate, bobPublic) 96 | require.Equal(t, bobSharedBytes, aliceSharedBytes) 97 | } 98 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | What is this? 3 | ============= 4 | 5 | CGO Go bindings to the CTIDH reference implementation. 6 | CTIDH is a post quantum cryptographic primitive called a NIKE, 7 | a noninteractive key exchange. 8 | 9 | Learn more about CTIDH: https://ctidh.isogeny.org/ 10 | 11 | 12 | How to Build 13 | ============ 14 | 15 | Step 1 16 | ------ 17 | 18 | Get high-ctidh: 19 | 20 | ``` 21 | git clone https://git.xx.network/elixxir/high-ctidh.git 22 | ``` 23 | 24 | Step 2 25 | ------ 26 | 27 | Build the CTIDH C shared library files: 28 | 29 | ``` 30 | cd high-ctidh 31 | ./autogen 32 | make libhighctidh_511.so libhighctidh_512.so libhighctidh_1024.so libhighctidh_2048.so 33 | cd .. 34 | ``` 35 | 36 | Step 3 37 | ------ 38 | 39 | Build your Go application. 40 | 41 | Let $P point to the ctidh_cgo directory: 42 | 43 | ``` 44 | export P=/home/human/code/ctidh_cgo 45 | ``` 46 | 47 | Copy the binding header file for your desired key size 48 | and set some environment variables: 49 | 50 | ``` 51 | export CTIDH_BITS=1024 52 | cp ${P}/binding${CTIDH_BITS}.h ${P}/binding.h 53 | export CGO_CFLAGS="-g -I${P} -I${P}/high-ctidh -DBITS=${CTIDH_BITS}" 54 | export CGO_LDFLAGS="-L${P}/high-ctidh -Wl,-rpath,${P}/high-ctidh -lhighctidh_${CTIDH_BITS}" 55 | ``` 56 | 57 | The the header file in place and these environment variables sets you 58 | should now be able to build your Go application which imports and 59 | makes use of the CTIDH Golang bindings. 60 | 61 | 62 | CTIDH Tests and Benchmarks 63 | =========================== 64 | 65 | In order to run the unit tests you'll have to set the CGO CFLAGS and 66 | LDFLAGS to indicate the absolute path to the library and header 67 | files. Here's an example using the LD_LIBRARY_PATH environment 68 | variable: 69 | 70 | ``` 71 | export CTIDH_BITS=512 72 | cp binding${CTIDH_BITS}.h binding.h 73 | export PWD=`pwd` 74 | export CGO_CFLAGS="-g -I${PWD}/high-ctidh -DBITS=${CTIDH_BITS}" 75 | export CGO_LDFLAGS="-L${PWD}/high-ctidh -l:libhighctidh_${CTIDH_BITS}.so" 76 | export LD_LIBRARY_PATH="${PWD}/high-ctidh" 77 | go test -v 78 | ``` 79 | 80 | It's also possible to compile your cgo binary using a set rpath which 81 | instructs it to load libraries from a relative path instead of setting 82 | LD_LIBRARY_PATH: 83 | 84 | ``` 85 | export CTIDH_BITS=512 86 | cp binding${CTIDH_BITS}.h binding.h 87 | export PWD=`pwd` 88 | export CGO_CFLAGS="-g -I${PWD}/high-ctidh -DBITS=${CTIDH_BITS}" 89 | export CGO_LDFLAGS="-L${PWD}/high-ctidh -Wl,-rpath,./high-ctidh -lhighctidh_${CTIDH_BITS}" 90 | go test -v 91 | ``` 92 | 93 | 94 | benchmarks 95 | ---------- 96 | 97 | Benchmark the DeriveSecret function for each public key size: 98 | 99 | ``` 100 | VALID_BIT_SIZES=('511' '512' '1024' '2048') 101 | for bits in "${VALID_BIT_SIZES[@]}" 102 | do 103 | export CTIDH_BITS=$bits 104 | cp binding${CTIDH_BITS}.h binding.h 105 | export PWD=`pwd` 106 | export CGO_CFLAGS="-g -I${PWD}/high-ctidh -DBITS=${CTIDH_BITS}" 107 | export CGO_LDFLAGS="-L${PWD}/high-ctidh -Wl,-rpath,./high-ctidh -lhighctidh_${CTIDH_BITS}" 108 | go test -bench=DeriveSecret 109 | done 110 | 111 | ``` 112 | 113 | 114 | test vectors 115 | ------------ 116 | 117 | Test vectors are a work in progress. 118 | 119 | ``` 120 | VALID_BIT_SIZES=('511' '512' '1024' '2048') 121 | for bits in "${VALID_BIT_SIZES[@]}" 122 | do 123 | export CTIDH_BITS=$bits 124 | cp binding${CTIDH_BITS}.h binding.h 125 | export PWD=`pwd` 126 | export CGO_CFLAGS="-g -I${PWD}/high-ctidh -DBITS=${CTIDH_BITS}" 127 | export CGO_LDFLAGS="-L${PWD}/high-ctidh -Wl,-rpath,./high-ctidh -lhighctidh_${CTIDH_BITS}" 128 | go test -v -tags=bits${CTIDH_BITS} -run=${CTIDH_BITS} 129 | done 130 | ``` 131 | 132 | 133 | License 134 | ======= 135 | 136 | This is public domain. 137 | -------------------------------------------------------------------------------- /vectors511_test.go: -------------------------------------------------------------------------------- 1 | //go:build bits511 2 | // +build bits511 3 | 4 | package ctidh 5 | 6 | import ( 7 | "encoding/hex" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func Test511BitVectorBlindingOperation(t *testing.T) { 14 | publicKeyHex := "025c39c2f0c91a549470c497566cf2ba4114e5facd24635e8cee6088a4c5ce73d91b18ccf02609c7f5f200b4a92ae18036a56b308add0fbf5b3d96a347e49f59" 15 | publicKeyBytes, err := hex.DecodeString(publicKeyHex) 16 | require.NoError(t, err) 17 | publicKey := new(PublicKey) 18 | err = publicKey.FromBytes(publicKeyBytes) 19 | require.NoError(t, err) 20 | 21 | blindingFactorHex := "44b793fa59e54f8ebcb3e3e2f9a35707964c12b55fa0dd39eda24046fafe383fd71098144eef914d92729f0836b46f4fe3cd0a75afb1ccb1fa2b36fcf15b7489dacfacdff74d5cc53973" 22 | blindingFactor, err := hex.DecodeString(blindingFactorHex) 23 | require.NoError(t, err) 24 | 25 | publicKey.Blind(blindingFactor) 26 | 27 | blindingOutputHex := "53defe8218c10d123390328c31165039854d31ab3099dce28a1fb31873a2104f16c02e59e5739078cd5dec5ec90f518178e2964569733e053c85248048361f32" 28 | blindingOutputBytes, err := hex.DecodeString(blindingOutputHex) 29 | require.NoError(t, err) 30 | 31 | require.Equal(t, blindingOutputBytes, publicKey.Bytes()) 32 | } 33 | 34 | func Test511BitVectors(t *testing.T) { 35 | // Alice 36 | alicePrivateKeyHex := "fd020202fb01ff020001fbffff0003020502ff020500fefefe02010501fb01fcfffc03010001000101fb000400fe000100fc030100000301fcfe0001ffff01ff00fe00ff000300ffff00" 37 | alicePrivateKeyBytes, err := hex.DecodeString(alicePrivateKeyHex) 38 | require.NoError(t, err) 39 | alicePrivateKey := new(PrivateKey) 40 | alicePrivateKey.FromBytes(alicePrivateKeyBytes) 41 | 42 | alicePublicKeyHex := "17f085e2f4ada10a3f0b15b0e3cff0e13ee915d3915dd779ae22c4664f067966c1ec2fae5fafb2af06222b8bdc3b7a649114ac5cc0dbd13cf35e4b5e61a74815" 43 | alicePublicKeyBytes, err := hex.DecodeString(alicePublicKeyHex) 44 | alicePublicKey := new(PublicKey) 45 | err = alicePublicKey.FromBytes(alicePublicKeyBytes) 46 | require.NoError(t, err) 47 | 48 | // Bob 49 | bobPrivateKeyHex := "02ff0401fe02fdff00040001fbfafefd00000002fe02fcfeff00fe010303020004fe0105fc00fd00ff0001fd04fe0302feff000000fe00ff02fefefdfe00010000030000000002fe0201" 50 | bobPrivateKeyBytes, err := hex.DecodeString(bobPrivateKeyHex) 51 | require.NoError(t, err) 52 | bobPrivateKey := new(PrivateKey) 53 | bobPrivateKey.FromBytes(bobPrivateKeyBytes) 54 | 55 | bobPublicKeyHex := "839aa1c32d36bb9e75cdb5c5ea62aea6ee56b8521dfae8bbfde9a70895f8f381b5a36bf5a87c2a5cda8b498711add07f21deaed998d985f7f79578759e233c25" 56 | bobPublicKeyBytes, err := hex.DecodeString(bobPublicKeyHex) 57 | bobPublicKey := new(PublicKey) 58 | err = bobPublicKey.FromBytes(bobPublicKeyBytes) 59 | require.NoError(t, err) 60 | 61 | // NIKE 62 | bobSharedBytes := DeriveSecret(bobPrivateKey, alicePublicKey) 63 | aliceSharedBytes := DeriveSecret(alicePrivateKey, bobPublicKey) 64 | require.Equal(t, bobSharedBytes, aliceSharedBytes) 65 | 66 | sharedSecretHex := "74cc3560ed96ca88ad111f2feb5002240bc3a389c1b768eb588e4c4432a9ed748a5341b68618ed49bb81b3554fb6a5bc41289513c5321faa9b8230611f50f311" 67 | sharedSecretBytes, err := hex.DecodeString(sharedSecretHex) 68 | require.NoError(t, err) 69 | 70 | require.Equal(t, sharedSecretBytes, aliceSharedBytes) 71 | } 72 | 73 | func TestPython511BitVectors(t *testing.T) { 74 | 75 | // Alice 76 | alicePrivateKeyHex := "ff01000503f801020003fffe0401fd000501fe030002fc03fffc00fc00000104fb00fe02040200000003feff0100ff0101000100fffe0302fffeff000301010100ff0100ffff00000100" 77 | alicePrivateKeyBytes, err := hex.DecodeString(alicePrivateKeyHex) 78 | require.NoError(t, err) 79 | alicePrivateKey := new(PrivateKey) 80 | alicePrivateKey.FromBytes(alicePrivateKeyBytes) 81 | 82 | alicePublicKeyHex := "27e65081c09f7dee63101e78309ef0ec892342435f04f237194d3fcef22fd850875fae3b7237d0d5952b9ab6351571967c6d0ba219158ee276192adc3a177713" 83 | alicePublicKeyBytes, err := hex.DecodeString(alicePublicKeyHex) 84 | alicePublicKey := new(PublicKey) 85 | err = alicePublicKey.FromBytes(alicePublicKeyBytes) 86 | require.NoError(t, err) 87 | 88 | // Bob 89 | bobPrivateKeyHex := "040000fdfafeff0003fffffa01fdfe02fe03fffc00ffff00fb030201fefd02fd01fe010300fd0202020300020101000100fa03ff00000000fd00ff030201020000000103000001010100" 90 | bobPrivateKeyBytes, err := hex.DecodeString(bobPrivateKeyHex) 91 | require.NoError(t, err) 92 | bobPrivateKey := new(PrivateKey) 93 | bobPrivateKey.FromBytes(bobPrivateKeyBytes) 94 | 95 | bobPublicKeyHex := "1c025d14327ca5dcad356f5f96df318c1d04434c554b7e79fc9a9a0c15e1f9b81665d5db19d5c1417dd0c7a31160db09b117817bb297faed7a068fb491627920" 96 | bobPublicKeyBytes, err := hex.DecodeString(bobPublicKeyHex) 97 | bobPublicKey := new(PublicKey) 98 | err = bobPublicKey.FromBytes(bobPublicKeyBytes) 99 | require.NoError(t, err) 100 | 101 | // NIKE 102 | bobSharedBytes := DeriveSecret(bobPrivateKey, alicePublicKey) 103 | aliceSharedBytes := DeriveSecret(alicePrivateKey, bobPublicKey) 104 | require.Equal(t, bobSharedBytes, aliceSharedBytes) 105 | 106 | sharedSecretHex := "5ecc8e5159cdb3bfac9281e183d9b3cbf2e289c28dee69f99b2fd840f141686fb133a3a40360a4e6056230a649be57b4e045b4c28c5558f80f57f85b43bbaf33" 107 | sharedSecretBytes, err := hex.DecodeString(sharedSecretHex) 108 | require.NoError(t, err) 109 | 110 | require.Equal(t, sharedSecretBytes, aliceSharedBytes) 111 | } 112 | -------------------------------------------------------------------------------- /vectors512_test.go: -------------------------------------------------------------------------------- 1 | //go:build bits512 2 | // +build bits512 3 | 4 | package ctidh 5 | 6 | import ( 7 | "encoding/hex" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func Test512BitVectorBlindingOperation(t *testing.T) { 14 | publicKeyHex := "928d8753b4749add1a24a1eb7f3654535cdc8137fadd54d548fd7870c2bafa7cbd02a605fa7567679a5a01914f8c8c411843ac5890fd34ba1e99f4f6bd9bf612" 15 | publicKeyBytes, err := hex.DecodeString(publicKeyHex) 16 | require.NoError(t, err) 17 | publicKey := new(PublicKey) 18 | err = publicKey.FromBytes(publicKeyBytes) 19 | require.NoError(t, err) 20 | 21 | blindingFactorHex := "4972d672d1acd58c3f3a3e3ba6d928c90e7dc4c35455fb9bdb5022de7018afd7ec09a13c8ed1892c8dfedac81d2c32956446ca9b37630879f92060e10040ea6d11ff8a9ef128a4328810" 22 | blindingFactor, err := hex.DecodeString(blindingFactorHex) 23 | require.NoError(t, err) 24 | 25 | publicKey.Blind(blindingFactor) 26 | 27 | blindingOutputHex := "a34b8ccd7b4f97859f1a0d2962b31a083d363a7d671340471516bd36f58def0b0203f44af2a799028a17a8856e18a7b603190e1a63adc215c0ae53d21c45761c" 28 | blindingOutputBytes, err := hex.DecodeString(blindingOutputHex) 29 | require.NoError(t, err) 30 | 31 | require.Equal(t, blindingOutputBytes, publicKey.Bytes()) 32 | } 33 | 34 | func Test512BitVectors(t *testing.T) { 35 | 36 | // Alice 37 | alicePrivateKeyHex := "0500ff0500fbfc04020a04010001050701ff01fcfc00fbff00fd010601fc00fffefd01f901f700fe000401ff0306fdff000102ff000204fdfd02ff01fc0000010401fd0000fffeff0500" 38 | alicePrivateKeyBytes, err := hex.DecodeString(alicePrivateKeyHex) 39 | require.NoError(t, err) 40 | alicePrivateKey := new(PrivateKey) 41 | alicePrivateKey.FromBytes(alicePrivateKeyBytes) 42 | 43 | alicePublicKeyHex := "a9f14cf61e8c8b9bf701c704ed66324ec3813eb7869106d636e4f72b09ac07e44979d45634f616ae12d876aec0de546f21cd9219d47e07da0929ec456d939338" 44 | alicePublicKeyBytes, err := hex.DecodeString(alicePublicKeyHex) 45 | alicePublicKey := new(PublicKey) 46 | err = alicePublicKey.FromBytes(alicePublicKeyBytes) 47 | require.NoError(t, err) 48 | 49 | // Bob 50 | bobPrivateKeyHex := "06fc0009fc01ff0201060304fcf501010004020104fd02fff8fefffc0103030100ffff040304ff0102fa0002ff000101fafdfe03ff0400fe01fa00fd0101ff03fe020101030200ff0001" 51 | bobPrivateKeyBytes, err := hex.DecodeString(bobPrivateKeyHex) 52 | require.NoError(t, err) 53 | bobPrivateKey := new(PrivateKey) 54 | bobPrivateKey.FromBytes(bobPrivateKeyBytes) 55 | 56 | bobPublicKeyHex := "1e4a6a12ae0218f3eda0213d28e640bf4e39a56847b0374576cb02a18219d7c64ea7e87414ce20eb45566f6cf6243e8fb6f4554e5553e6d4418b4ca609ff6c3a" 57 | bobPublicKeyBytes, err := hex.DecodeString(bobPublicKeyHex) 58 | bobPublicKey := new(PublicKey) 59 | err = bobPublicKey.FromBytes(bobPublicKeyBytes) 60 | require.NoError(t, err) 61 | 62 | // NIKE 63 | bobSharedBytes := DeriveSecret(bobPrivateKey, alicePublicKey) 64 | aliceSharedBytes := DeriveSecret(alicePrivateKey, bobPublicKey) 65 | require.Equal(t, bobSharedBytes, aliceSharedBytes) 66 | 67 | sharedSecretHex := "24081588d4f3232f788e4e65db4870a223942ad272722a70577c26533c93adcd798cd166f26bfbafa6d6e428bf502a98e753a5a17ba2669869b2082f50266932" 68 | sharedSecretBytes, err := hex.DecodeString(sharedSecretHex) 69 | require.NoError(t, err) 70 | 71 | require.Equal(t, sharedSecretBytes, aliceSharedBytes) 72 | } 73 | 74 | func TestPython512BitVectors(t *testing.T) { 75 | 76 | // Alice 77 | alicePrivateKeyHex := "fcfbfd01f6090104fe09ff0502040000060100fcfefc06ff04060000ff03fe010300010307ff01040201020006020000fcfefd01fe0000fdf9fdff040104000201fe0001fd020201fe00" 78 | alicePrivateKeyBytes, err := hex.DecodeString(alicePrivateKeyHex) 79 | require.NoError(t, err) 80 | alicePrivateKey := new(PrivateKey) 81 | alicePrivateKey.FromBytes(alicePrivateKeyBytes) 82 | 83 | alicePublicKeyHex := "f0e3123870580f84f10e269a5150baaaf7058a6f0437cb8678c5ad6a0dddd3355c76435ae054a873e76bf5f8bc58ec29053d02162c7d3f309764443e2a3f0f38" 84 | alicePublicKeyBytes, err := hex.DecodeString(alicePublicKeyHex) 85 | alicePublicKey := new(PublicKey) 86 | err = alicePublicKey.FromBytes(alicePublicKeyBytes) 87 | require.NoError(t, err) 88 | 89 | // Bob 90 | bobPrivateKeyHex := "02f90009ff06ff03fb0701010501fffafdffff070204fdfefc02fe04fc00060302fefeff01f9020002fffb0000fe02ff00f6030003ff01010105fbfffd01fffe0302fc000101fc000101" 91 | bobPrivateKeyBytes, err := hex.DecodeString(bobPrivateKeyHex) 92 | require.NoError(t, err) 93 | bobPrivateKey := new(PrivateKey) 94 | bobPrivateKey.FromBytes(bobPrivateKeyBytes) 95 | 96 | bobPublicKeyHex := "7369aaee2b543f17655fd57a78e03140b9a7fda3773651920c89fcd2aa9875dd633c3762f39fbda81961c70b0716974352ad5833564c6764ee082f17545b374d" 97 | bobPublicKeyBytes, err := hex.DecodeString(bobPublicKeyHex) 98 | bobPublicKey := new(PublicKey) 99 | err = bobPublicKey.FromBytes(bobPublicKeyBytes) 100 | require.NoError(t, err) 101 | 102 | // NIKE 103 | bobSharedBytes := DeriveSecret(bobPrivateKey, alicePublicKey) 104 | aliceSharedBytes := DeriveSecret(alicePrivateKey, bobPublicKey) 105 | require.Equal(t, bobSharedBytes, aliceSharedBytes) 106 | 107 | sharedSecretHex := "0d84960ea3c52ad6264a53915757d1ff8733629914577151140ae28bd28325bc31151ae3a1447e0d68aae42abcc63dae249072a8e729678ab73fd333b32a7a3d" 108 | sharedSecretBytes, err := hex.DecodeString(sharedSecretHex) 109 | require.NoError(t, err) 110 | 111 | require.Equal(t, sharedSecretBytes, aliceSharedBytes) 112 | } 113 | -------------------------------------------------------------------------------- /vectors1024_test.go: -------------------------------------------------------------------------------- 1 | //go:build bits1024 2 | // +build bits1024 3 | 4 | package ctidh 5 | 6 | import ( 7 | "encoding/hex" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func Test1024BitVectorBlindingOperation(t *testing.T) { 14 | publicKeyHex := "859070e07094657ae90acfa5e03c0342cb1909bf73cc1d0992ef48f533444bdc334846872333cbf17b0b3a763f64b4d5435c91742269d6dfcfe5347473b28f881045a55f3e10a7a7dd5a7192013a932d29703a1236eb1964563a9892ab19fffa3590a0f0a2e02a2205baf6af83d192822f24516fb311506f4cc18687a18c1e0c" 15 | publicKeyBytes, err := hex.DecodeString(publicKeyHex) 16 | require.NoError(t, err) 17 | publicKey := new(PublicKey) 18 | err = publicKey.FromBytes(publicKeyBytes) 19 | require.NoError(t, err) 20 | 21 | blindingFactorHex := "82b843e2e941649c8e25aafde8e088e2c3406f8a1cd5803566e9204c2178bf68e7fa0febcc721ef527d514c4a79d29d549f59c876a69b18d3b7112f2b2b2b68b6acb0037a60c00981c7f6edfbaeccba1dc54df5dd85c96256b9649f3df3676dba7578163075b4fff7012c2fadb9bd03b3b9488b5577bab3918d1899b3cba0ff5b046" 22 | blindingFactor, err := hex.DecodeString(blindingFactorHex) 23 | require.NoError(t, err) 24 | 25 | publicKey.Blind(blindingFactor) 26 | 27 | blindingOutputHex := "b7f1fb4cba440e61d516d4cdb6a8b542c057b76eb4b277e0114a544c943756721ee2d09136b0ce97eb099961a6b383820cf7aebec2217b6f7cb7169aec7d00788b5bf549e274a743d496258b99f3cd36d176d253cc858719f0db4027959d2c8fd8f731c5101cba9198dabe11ebf3f67191bd8210b5a5fd9387ff5892d2565200" 28 | blindingOutputBytes, err := hex.DecodeString(blindingOutputHex) 29 | require.NoError(t, err) 30 | 31 | require.Equal(t, blindingOutputBytes, publicKey.Bytes()) 32 | } 33 | 34 | func Test1024BitVectors(t *testing.T) { 35 | // Alice 36 | alicePrivateKeyHex := "fe0001010000fe0100fe00ff00fc0300ffffff0000ff0100000000ff01010200000201fe01000100ff0000fdff010001ffffff03fd0000000000feff000101ff000401000100000100040000010001ff00000001000100000101ffffff010001ff00ff00ffff0000fe000100000100ff0000000002ff0000fe0000010000ff000000" 37 | alicePrivateKeyBytes, err := hex.DecodeString(alicePrivateKeyHex) 38 | require.NoError(t, err) 39 | alicePrivateKey := new(PrivateKey) 40 | alicePrivateKey.FromBytes(alicePrivateKeyBytes) 41 | 42 | alicePublicKeyHex := "b962dadf244d6239ab74d808b0a88b2078b549bb03fab005ef6a97c1ee448bdc5a37892aaddf762e0157de5670320e8007398fb3eeab00a09fcbfe3caffb1fcebd03c38144e76b5d1dcd623871dbc6fe13470a23901dbadac77626fd05f891f18416a94123f9333ef1bdfb7570fa248f2567e33a8661c1411c42963b93e7a506" 43 | alicePublicKeyBytes, err := hex.DecodeString(alicePublicKeyHex) 44 | alicePublicKey := new(PublicKey) 45 | err = alicePublicKey.FromBytes(alicePublicKeyBytes) 46 | require.NoError(t, err) 47 | 48 | // Bob 49 | bobPrivateKeyHex := "ffff01fe0000ff000102010103000000ff02000102fe0000000100fffefeff00000000fd01fe00fefd0001000000fc00fe0000fe000102000100000002feff0001ff0001010100ff01ffff0000010102000000020100010003fffd0000fe000000ff00ff01000001fd0001ff0000000001010000ff0100ffff010100ff000000ff00" 50 | bobPrivateKeyBytes, err := hex.DecodeString(bobPrivateKeyHex) 51 | require.NoError(t, err) 52 | bobPrivateKey := new(PrivateKey) 53 | bobPrivateKey.FromBytes(bobPrivateKeyBytes) 54 | 55 | bobPublicKeyHex := "e859133b1bb959a4f17135cd337477141f81684317b30a7f14bad81a867df388477c2bf7a7af738618b568f323b91762f2282706875341b9343a3cd0450073783a91fc71edca8c8b30f9ec6379137c91ce33dcae9dc3c7fd1a951925e299bafdbff6a29dcdb9ae1207f7fb986b6b1087bf05b79c542dca25993c5a43ef7dc105" 56 | bobPublicKeyBytes, err := hex.DecodeString(bobPublicKeyHex) 57 | bobPublicKey := new(PublicKey) 58 | err = bobPublicKey.FromBytes(bobPublicKeyBytes) 59 | require.NoError(t, err) 60 | 61 | // NIKE 62 | bobSharedBytes := DeriveSecret(bobPrivateKey, alicePublicKey) 63 | aliceSharedBytes := DeriveSecret(alicePrivateKey, bobPublicKey) 64 | require.Equal(t, bobSharedBytes, aliceSharedBytes) 65 | 66 | sharedSecretHex := "411abafeca991f77b6f9263721ca3e2898031871e18d91b61c33c8664a9fc3fccf331729a9dd60465687e53c3d7649abfd4a3e32f4ea86e351535c9b281a76a74fa6b057d94403e55941de7e91432e2e85cc8f5b13fa28314a8dc8f09360e44c802bfc8b036451b26bc54200e133dde3976aa1f4885277a7692da9d38c09e301" 67 | sharedSecretBytes, err := hex.DecodeString(sharedSecretHex) 68 | require.NoError(t, err) 69 | 70 | require.Equal(t, sharedSecretBytes, aliceSharedBytes) 71 | } 72 | 73 | func TestPython1024BitVectors(t *testing.T) { 74 | 75 | // Alice 76 | alicePrivateKeyHex := "000200fffd0000ff03fffe0200010000fd00ff0000fffd010001fe01000001ff00ff020100fe00fffd010100000101feff0100010101fd000000000000fefffffe02000101020000ff0101020000ffffff00000002000001020101ff00ff0200ffff0000000100000000000001ffff00000100fd000000010000fe00ffff00000000" 77 | alicePrivateKeyBytes, err := hex.DecodeString(alicePrivateKeyHex) 78 | require.NoError(t, err) 79 | alicePrivateKey := new(PrivateKey) 80 | alicePrivateKey.FromBytes(alicePrivateKeyBytes) 81 | 82 | alicePublicKeyHex := "f364c4b220d57528d6b64432e93fb40495177faf9a224955f34b5700cf1cf35be7c476e43681a375602fc57eba16aa0c5c4ae02f3031d55d84c2cb679969074216ca0f114d7c798dc12c65b9820d2dce650070c79f992f34c6653963d62fba82a9f48293940ec6001093a06023ee0b80022d19e33d3a669934cbd289c87ddb01" 83 | alicePublicKeyBytes, err := hex.DecodeString(alicePublicKeyHex) 84 | alicePublicKey := new(PublicKey) 85 | err = alicePublicKey.FromBytes(alicePublicKeyBytes) 86 | require.NoError(t, err) 87 | 88 | // Bob 89 | bobPrivateKeyHex := "00fe00fe0101000200fe0002000100fe01000001020200000100ff040000ff000003010002000001010000fc0100010200fe00010000fe000000fe00000201ff000202ffff000000ff00ff0002ff0101fe010000000101ff0001fe00000001000000ff00ff020100000000ff00ffff0000ff00000000ffff0003ff000100ff000000" 90 | bobPrivateKeyBytes, err := hex.DecodeString(bobPrivateKeyHex) 91 | require.NoError(t, err) 92 | bobPrivateKey := new(PrivateKey) 93 | bobPrivateKey.FromBytes(bobPrivateKeyBytes) 94 | 95 | bobPublicKeyHex := "90d51cc0f48b0ce2712bc8305e7415300bde7feef634e17211ae493ea57b56d1ad81914e85e3b8b43275e7a31c9d440f3f88ef476a31c7e504520f7b538bcbe80fd3bbbc76726c4c37c6c8f9f857618602fcbbc6899e8ac420de32e1ebb1f1178dd13f600afba82276b5f5e6b40dc421b5c3b1f342a9152009b1fae95d372303" 96 | bobPublicKeyBytes, err := hex.DecodeString(bobPublicKeyHex) 97 | bobPublicKey := new(PublicKey) 98 | err = bobPublicKey.FromBytes(bobPublicKeyBytes) 99 | require.NoError(t, err) 100 | 101 | // NIKE 102 | bobSharedBytes := DeriveSecret(bobPrivateKey, alicePublicKey) 103 | aliceSharedBytes := DeriveSecret(alicePrivateKey, bobPublicKey) 104 | require.Equal(t, bobSharedBytes, aliceSharedBytes) 105 | 106 | sharedSecretHex := "b5ab3b4d9cac68c451a43d1b499e190d462788362089ca5f3e4462c1502bb06cc820fe2e46c0f9ddaf8de6fcf8c0b4238e677497ebc6f5bb622a894c3c485c9e16142579392b6af434db46b146416aab5d5bd43c3d0f1bc55755f1af93d137d20540e65fc54e7b2b564dceec6484dc2b8bdd30db2b4ea7ba86adecfcb3e7ba08" 107 | sharedSecretBytes, err := hex.DecodeString(sharedSecretHex) 108 | require.NoError(t, err) 109 | 110 | require.Equal(t, sharedSecretBytes, aliceSharedBytes) 111 | } 112 | -------------------------------------------------------------------------------- /vectors2048_test.go: -------------------------------------------------------------------------------- 1 | //go:build bits2048 2 | // +build bits2048 3 | 4 | package ctidh 5 | 6 | import ( 7 | "encoding/hex" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func Test2048BitVectorBlindingOperation(t *testing.T) { 14 | publicKeyHex := "21418e787fe5ca6b7ac5c9fc4463e6e1ea5ef8d7b11bb96f6d1a7d2a70427c7a9f6ed48c32c390f573f9e6e01ef23ad84903492eea776470f68b13cadedbb1eb7cc184ff363e883d45603646301c2a477ef3c13c213503b8c21ee637ddb6b10f5f215bc7a07d3451b6bdac99cff25a1c795ade4b3b61d2a8800269d79c0b5b7d30bc917e42ed84fc55dd2cf7e26dfb024cb9af7cdde07b32ae23c2b6c47f815767e0e184b22b80acbfee433586f4d8a7e57d83dae8ed3f37553367d4e2a183c9771548ad9e25ba7f86a40bacc71911fa5b9a059b18ac9fe358e12bd5f315385f9aed96ede4ed2ff8089de64e9caf8a9b1d615b610fbc95c57f25ce9b445d7533" 15 | publicKeyBytes, err := hex.DecodeString(publicKeyHex) 16 | require.NoError(t, err) 17 | publicKey := new(PublicKey) 18 | err = publicKey.FromBytes(publicKeyBytes) 19 | require.NoError(t, err) 20 | 21 | blindingFactorHex := "dcd05b1450127b4ce5670e5796c63686c9afb12735f155d883250aabcd98e49ddba9d9edb632181d891ee4d5e78550b45e8e7a72365fede727d5f90acad97e7a2b70cace99765e8193e3d439d55b64576af0cca5fded676daa42f00809670572f8d3e48cd02f87d0c3c051c5730f1e9e84cf6b3c0c11311ce4f4ce110336f373d1247d339341e692b060087b0816e77879282b62211a8287281c487ba4d87e336f758093763342ec2ed4c256c2572d985d7f0b5fd2bba61203a8633277930d6840ab8865189dcfc9a63b82307e99818f52cfb158cb55a93e55387e1a08976823675e0b9c0e5a47" 22 | blindingFactor, err := hex.DecodeString(blindingFactorHex) 23 | require.NoError(t, err) 24 | 25 | publicKey.Blind(blindingFactor) 26 | 27 | blindingOutputHex := "337ac185e41400e58970f28a424e13e808468b0eec1e791ff0eb31924747207a77177ba87e63a21a0c13c6563a5ab0cd53edf0e58bc6a01af1df283770120831643ca1f5ba168f0e526c6e81708a78c862daa50d8a0ccb22547ab35c782fc5e732b442742fcee23897820441e2359387ff79973fb86372aa0e80097bab6066a0e12856d36803b8e811f187e74fe9092d624d43d559785f8e0ec99b4935117e7a876576999a337d7ff45f86532fdeb46799e2535b4760b24311f6888f21743a9c2f927e970df6bc525b07b1cbee786f084e096d414c60d4c2d87cd4237d127e1a826de5469bdcb9d1c63848e30e996a3a0df7a0299277a5abbaaddd4faa3a762a" 28 | blindingOutputBytes, err := hex.DecodeString(blindingOutputHex) 29 | require.NoError(t, err) 30 | 31 | require.Equal(t, blindingOutputBytes, publicKey.Bytes()) 32 | } 33 | 34 | func Test2048BitVectors(t *testing.T) { 35 | // Alice 36 | alicePrivateKeyHex := "000000000000010000000000ff0000ff00010000ff00ff000000000000ff000100ff00000000fe00000100000000010000ffff000000ff00000000000100010000ff0100000000000000ff0000ff000000ff00000000000000000000000000fe0000ff000000000000000000fe0100ff00010000010000000000ff0000ffff00000101000100010000000000000101000000000000ff000001ff000001ff000100000000000000000101ff00000000000000ff01000000000000000001000101000000000000000000ff0000000000000100000000000000000000000000000000ff0000000000" 37 | alicePrivateKeyBytes, err := hex.DecodeString(alicePrivateKeyHex) 38 | require.NoError(t, err) 39 | alicePrivateKey := new(PrivateKey) 40 | alicePrivateKey.FromBytes(alicePrivateKeyBytes) 41 | 42 | alicePublicKeyHex := "21e57c6198f94739d91dfd3ce3bf73c0a272309c49a6495f47d14b8facf7abcf2f20668e9c3eb8c1630d8259596a035c17e153825b93fa1df44bc172e7b48d6b79291ce4fa4cc54a7e52c1f466d9de824d71a4164c2b0e50d61cbf44aa16a3e3ff8f9d39f92a4835c144f1f64e34a72561648c8b7d447681c1b8c97e36c9f73d9666b3749515a32a9f293ac30d1a3fe0d3e4c8ef4907ae1d074a1ee994adf35242c4a743bc47215c816539ff11691dd2f20be8f81b499696f01c5053437a594f1c1f30ed0caca6c4966b6c4115b343b18af1d6648725d5746ed45bc78b010217b172c400f2a7608ee5a991b3a03990709754f0f4e2870d921e16a80920b8c300" 43 | alicePublicKeyBytes, err := hex.DecodeString(alicePublicKeyHex) 44 | alicePublicKey := new(PublicKey) 45 | err = alicePublicKey.FromBytes(alicePublicKeyBytes) 46 | require.NoError(t, err) 47 | 48 | // Bob 49 | bobPrivateKeyHex := "0000000000000000000100010000000100000000000000ff01ff0000ff000001ff0000000000fe01000000ff00000000ff0000000000010000ff0000000100000000fe0000000000ff000000ff000000000000000000000000ff00000000ff0001000000000002000000ff0000000000ff00ff00ff00000000fe0000ff00000000ff000001ff0000ff00000000ff00ff00000000000000ff00000001000002000000000000ff000100ff00000000010000000000ff0000ffff000000000000ff0001000000ff000001000000000000ff000000000000000000000000010000000000000000ff00" 50 | bobPrivateKeyBytes, err := hex.DecodeString(bobPrivateKeyHex) 51 | require.NoError(t, err) 52 | bobPrivateKey := new(PrivateKey) 53 | bobPrivateKey.FromBytes(bobPrivateKeyBytes) 54 | 55 | bobPublicKeyHex := "4c494a11faa365e6b22bce7f3074b3285668f5ed99e83492f3860e4957a65ca0da1ce5e8a86e880bdc8b91cb57962114d3ae94de4399953345ec6a8e7a76e9c34b6b7bde647e7339e48a19ca05fcc0b69c25369588f85e41cbbee54543e3886a2f6213d7d1fd04892420501df582cc2ce974a13d2c71131b8d36aa304c5222532b064ef0a06886bfeffae4049672fcbb1f92ee4cf99b4cb83d3efa0e5a461b425d900147570e09610159d6af16628957dc781b5c84e8f198d6041ffdaf5a67e11f054f1876981fa52cea9a796a20052d1c68df0aa51b682c5ebbf9c2464fdfa90ac0e619097c2f713ced9dd0a2c4fabdd373626936a282281110fde352da7729" 56 | bobPublicKeyBytes, err := hex.DecodeString(bobPublicKeyHex) 57 | bobPublicKey := new(PublicKey) 58 | err = bobPublicKey.FromBytes(bobPublicKeyBytes) 59 | require.NoError(t, err) 60 | 61 | // NIKE 62 | bobSharedBytes := DeriveSecret(bobPrivateKey, alicePublicKey) 63 | aliceSharedBytes := DeriveSecret(alicePrivateKey, bobPublicKey) 64 | require.Equal(t, bobSharedBytes, aliceSharedBytes) 65 | 66 | sharedSecretHex := "660261a31b1ce1ba858ae7a0c17314b5587f13dc1c31a6eb7a38933037705bfe7b19cfd387d32dc0ea99de95f6fa1bfc7667066b668542358b6cd244b64e75a558130d583761c21c5d67f012acc846319e23c73cbcee02bb26a397f2c06fa7f73332d9761a1dd19ef73b9d8f3a8a235fc9f85d73da4240f7de268cf7dc2682a56d4afca6bad9fbfd899d9d3d22273b3f12e37dba810fd76e4ccacb2e1c7b7e42db692cb3b7fb7ffb3077e7674a4fec683c43eef1a92df1789e764fc08c9e02c3db0f8df04450f5f6a3f84b1380c061351feaa9e7f4d3814dd334b8100437432619abb1b874e4d93460430921d27cd8affdbca1236bea9307a91c97eeb2f0d72d" 67 | sharedSecretBytes, err := hex.DecodeString(sharedSecretHex) 68 | require.NoError(t, err) 69 | 70 | require.Equal(t, sharedSecretBytes, aliceSharedBytes) 71 | } 72 | 73 | func TestPython2048BitVectors(t *testing.T) { 74 | 75 | // Alice 76 | alicePrivateKeyHex := "00010000000000000000000000ff000000ffff02ff00000000000000ff000000020000fe01000000000000000001ff0000010000000000ff00000000ff00000100ff0000ff00000001000001000000010000010000000000ff000000ff000001000000000001ff00010000000000ff00000001000000ff0000000000030000ffffff00000000000000000001ff00ff000000000000010100000000ff000000000000ff00020000000000000000ff00000001000000ffff0000000000ff000000000000000100000101000000ff00000000000000000000000000000000ff000000000001000000" 77 | alicePrivateKeyBytes, err := hex.DecodeString(alicePrivateKeyHex) 78 | require.NoError(t, err) 79 | alicePrivateKey := new(PrivateKey) 80 | alicePrivateKey.FromBytes(alicePrivateKeyBytes) 81 | 82 | alicePublicKeyHex := "b2af3db1d3070879a0a0f4dbabd8c4d4e44536ad3caa22a1e212fffaa9886611b09904ba5e2d889e7aa54186d9b134e01a06da93f5c61b5c035a3d738388a121e3b6774f298fedaca36edfc4f1c5c10153ad40fa8a116f9668189bbbae25c09d42d34703756076e3326c6302dade803bbcdbb6a66650bf3115c72b40d9e71eca2309298a5b2c0469d62c1fa46a956287617395e04e7e3842f71e060ca73738461bb30f2ca3329c2c8bbdce4b4f4b47ef3c851799144003cab417d55988ddbe23920fd92692d00eb3aa1e63d04651ca4e10a885c7af948ebf93dae875152ca10a47feb67d79c7536c941122996a5d81e8ed3306056b2c31048edd3e8bbfa28c38" 83 | alicePublicKeyBytes, err := hex.DecodeString(alicePublicKeyHex) 84 | alicePublicKey := new(PublicKey) 85 | err = alicePublicKey.FromBytes(alicePublicKeyBytes) 86 | require.NoError(t, err) 87 | 88 | // Bob 89 | bobPrivateKeyHex := "0000000100000000000000ff00000100ff000000000000000001fe0000010000020000010000ff00000000000100010001000000ff00000100000000ff000000000000000000ffff00000000000000000000ff00fe0000000000ff00000100000000ff000001000000ff00ff000000000000010002000000ff00000001ff0000ff00ff00000000000000000001000000000100000100000001000000ff0000ff010000000000000101ff0000000000000100000100000001000000ff00000000000000010000ff0000ff00000000000000010000000000000000000000000000ff000000010000" 90 | bobPrivateKeyBytes, err := hex.DecodeString(bobPrivateKeyHex) 91 | require.NoError(t, err) 92 | bobPrivateKey := new(PrivateKey) 93 | bobPrivateKey.FromBytes(bobPrivateKeyBytes) 94 | 95 | bobPublicKeyHex := "135d73849ad45f7e14134b5b550e9700923cdd2f2c6eba69a6a34317120c0fcba202b171924ff08eaa6b0c7635b457e9d5e3ce2a09ea562704166d59ca57fb3ae8046a0aa330c60978add40ea6e3c386c4ca3c7b33ef02f8aec3f166c31949e93a30e665c971588faa4eb4ef07f3143fb6c0efd4f7264f1dde8fdb6d277657b2129439b7f01aba57b82efa2c2fe12a637b99a5f974ae08c3ae24a2f70eff86947dbde7f7624b082143ea3e4864afbb3d1a40af0f2e1acc09eb07922d05f99072fdd534f3d96edd09dc642cbc452345a49d0f30b515078a76696bed53c175b436c58bbcfb95893b99f252896bb3d29bb711d401a89969aeaf7b88409c76b4e834" 96 | bobPublicKeyBytes, err := hex.DecodeString(bobPublicKeyHex) 97 | bobPublicKey := new(PublicKey) 98 | err = bobPublicKey.FromBytes(bobPublicKeyBytes) 99 | require.NoError(t, err) 100 | 101 | // NIKE 102 | bobSharedBytes := DeriveSecret(bobPrivateKey, alicePublicKey) 103 | aliceSharedBytes := DeriveSecret(alicePrivateKey, bobPublicKey) 104 | require.Equal(t, bobSharedBytes, aliceSharedBytes) 105 | 106 | sharedSecretHex := "f61ebdb51cff8de704e1940b702b7359f3936f632b9ac33a18d9f58f85153875e14fdc701912cc8717f0cb4c32729bc5eb9dbfc9ef207281103ae381f2ba0553686cbc43c279d1da8897e5fbab50e2a05e38ef7b012a85b856ebb3c1ebd133dc32f710dd6d67f80093b37402e5581f350f09188ac97b2ea7a14fbaa3c5db0bb38036ac2e81e34f1a04fae0fd91b90b3bca1fa3ae5b5bd37e0edebf08d806eb4cd9ab136289c9e86aba3f8839fabec86ae0cdbd794409a6b6f81b3a5c5f9f56da5e9bdeaf8f6d802be6f987ab5772f35b3855291c9ab3b1848d654841a24e014f7a112cf7591d16bf1d33b2d46e4294fca42cacb1c2eacdbe9040ab794906353f" 107 | sharedSecretBytes, err := hex.DecodeString(sharedSecretHex) 108 | require.NoError(t, err) 109 | 110 | require.Equal(t, sharedSecretBytes, aliceSharedBytes) 111 | } 112 | -------------------------------------------------------------------------------- /binding.go: -------------------------------------------------------------------------------- 1 | package ctidh 2 | 3 | // #include "binding.h" 4 | // #include 5 | import "C" 6 | import ( 7 | "bytes" 8 | "crypto/hmac" 9 | "encoding/pem" 10 | "fmt" 11 | "io/ioutil" 12 | "unsafe" 13 | ) 14 | 15 | var ( 16 | // PublicKeySize is the size in bytes of the public key. 17 | PublicKeySize int 18 | 19 | // PrivateKeySize is the size in bytes of the private key. 20 | PrivateKeySize int 21 | 22 | // ErrBlindDataSizeInvalid indicates that the blinding data size was invalid. 23 | ErrBlindDataSizeInvalid error = fmt.Errorf("%s: blinding data size invalid", Name()) 24 | 25 | // ErrPublicKeyValidation indicates a public key validation failure. 26 | ErrPublicKeyValidation error = fmt.Errorf("%s: public key validation failure", Name()) 27 | 28 | // ErrPublicKeySize indicates the raw data is not the correct size for a public key. 29 | ErrPublicKeySize error = fmt.Errorf("%s: raw public key data size is wrong", Name()) 30 | 31 | // ErrPrivateKeySize indicates the raw data is not the correct size for a private key. 32 | ErrPrivateKeySize error = fmt.Errorf("%s: raw private key data size is wrong", Name()) 33 | 34 | // ErrCTIDH indicates a group action failure. 35 | ErrCTIDH error = fmt.Errorf("%s: group action failure", Name()) 36 | ) 37 | 38 | // ErrPEMKeyTypeMismatch returns an error indicating that we tried 39 | // to decode a PEM file containing a differing key type than the one 40 | // we expected. 41 | func ErrPEMKeyTypeMismatch(gotType, wantType string) error { 42 | return fmt.Errorf("%s: Attempted to decode a PEM bytes of type %s"+ 43 | " which differs from the type we want %s", 44 | Name(), 45 | gotType, 46 | wantType) 47 | } 48 | 49 | // PublicKey is a public CTIDH key. 50 | type PublicKey struct { 51 | publicKey C.public_key 52 | } 53 | 54 | // NewEmptyPublicKey returns an uninitialized 55 | // PublicKey which is suitable to be loaded 56 | // via some serialization format via FromBytes 57 | // or FromPEMFile methods. 58 | func NewEmptyPublicKey() *PublicKey { 59 | return new(PublicKey) 60 | } 61 | 62 | // NewPublicKey creates a new public key from 63 | // the given key material or panics if the 64 | // key data is not PublicKeySize. 65 | func NewPublicKey(key []byte) *PublicKey { 66 | k := new(PublicKey) 67 | err := k.FromBytes(key) 68 | if err != nil { 69 | panic(err) 70 | } 71 | return k 72 | } 73 | 74 | // String returns a string identifying 75 | // this type as a CTIDH public key. 76 | func (p *PublicKey) String() string { 77 | return Name() + "_PublicKey" 78 | } 79 | 80 | // ToPEM writes out the PublicKey to a PEM block and returns it 81 | func (p *PublicKey) ToPEM() (*pem.Block, error) { 82 | keyType := Name() + " PUBLIC KEY" 83 | 84 | zeros := make([]byte, PublicKeySize) 85 | if bytes.Equal(p.Bytes(), zeros) { 86 | return nil, fmt.Errorf("%s: attemted to serialize scrubbed key", 87 | Name()) 88 | } 89 | blk := &pem.Block{ 90 | Type: keyType, 91 | Bytes: p.Bytes(), 92 | } 93 | return blk, nil 94 | } 95 | 96 | // ToPEMFile writes out the PublicKey to a PEM file at path f. 97 | func (p *PublicKey) ToPEMFile(f string) error { 98 | blk, err := p.ToPEM() 99 | if err != nil { 100 | return err 101 | } 102 | return ioutil.WriteFile(f, pem.EncodeToMemory(blk), 0600) 103 | } 104 | 105 | // FromPEM reads the PublicKey from a PEM encoded byte slice. 106 | func (p *PublicKey) FromPEM(pemBytes []byte) error { 107 | keyType := Name() + " PUBLIC KEY" 108 | 109 | blk, _ := pem.Decode(pemBytes) 110 | if blk == nil { 111 | return fmt.Errorf("%s: failed to decode PEM", Name()) 112 | } 113 | if blk.Type != keyType { 114 | return ErrPEMKeyTypeMismatch(blk.Type, keyType) 115 | } 116 | return p.FromBytes(blk.Bytes) 117 | } 118 | 119 | // FromPEMFile reads the PublicKey from a PEM file at path f. 120 | func (p *PublicKey) FromPEMFile(f string) error { 121 | buf, err := ioutil.ReadFile(f) 122 | if err != nil { 123 | return err 124 | } 125 | err = p.FromPEM(buf) 126 | if err != nil { 127 | return fmt.Errorf("%s in file %s", err.Error(), f) 128 | } 129 | return nil 130 | } 131 | 132 | // Reset resets the PublicKey to all zeros. 133 | func (p *PublicKey) Reset() { 134 | zeros := make([]byte, PublicKeySize) 135 | err := p.FromBytes(zeros) 136 | if err != nil { 137 | panic(err) 138 | } 139 | } 140 | 141 | // Bytes returns the PublicKey as a byte slice. 142 | func (p *PublicKey) Bytes() []byte { 143 | return C.GoBytes(unsafe.Pointer(&p.publicKey.A.x.c), C.int(C.UINTBIG_LIMBS*8)) 144 | } 145 | 146 | // FromBytes loads a PublicKey from the given byte slice. 147 | func (p *PublicKey) FromBytes(data []byte) error { 148 | if len(data) != PublicKeySize { 149 | return ErrPublicKeySize 150 | } 151 | 152 | p.publicKey = *((*C.public_key)(unsafe.Pointer(&data[0]))) 153 | if !C.validate(&p.publicKey) { 154 | return ErrPublicKeyValidation 155 | } 156 | 157 | return nil 158 | } 159 | 160 | // Equal is a constant time comparison of the two public keys. 161 | func (p *PublicKey) Equal(publicKey *PublicKey) bool { 162 | return hmac.Equal(p.Bytes(), publicKey.Bytes()) 163 | } 164 | 165 | // Blind performs a blinding operation 166 | // and mutates the public key. 167 | // See notes below about blinding operation with CTIDH. 168 | func (p *PublicKey) Blind(blindingFactor []byte) error { 169 | if len(blindingFactor) != PrivateKeySize { 170 | return ErrBlindDataSizeInvalid 171 | } 172 | var err error 173 | blinded, err := Blind(blindingFactor, p) 174 | if err != nil { 175 | panic(err) 176 | } 177 | p.publicKey = blinded.publicKey 178 | return nil 179 | } 180 | 181 | // PrivateKey is a private CTIDH key. 182 | type PrivateKey struct { 183 | privateKey C.private_key 184 | } 185 | 186 | // NewEmptyPrivateKey returns an uninitialized 187 | // PrivateKey which is suitable to be loaded 188 | // via some serialization format via FromBytes 189 | // or FromPEMFile methods. 190 | func NewEmptyPrivateKey() *PrivateKey { 191 | return new(PrivateKey) 192 | } 193 | 194 | // DeriveSecret derives a shared secret. 195 | func (p *PrivateKey) DeriveSecret(publicKey *PublicKey) []byte { 196 | return DeriveSecret(p, publicKey) 197 | } 198 | 199 | // String returns a string identifying 200 | // this type as a CTIDH private key. 201 | func (p *PrivateKey) String() string { 202 | return Name() + "_PrivateKey" 203 | } 204 | 205 | // Reset resets the PrivateKey to all zeros. 206 | func (p *PrivateKey) Reset() { 207 | zeros := make([]byte, PrivateKeySize) 208 | err := p.FromBytes(zeros) 209 | if err != nil { 210 | panic(err) 211 | } 212 | } 213 | 214 | // Bytes serializes PrivateKey into a byte slice. 215 | func (p *PrivateKey) Bytes() []byte { 216 | return C.GoBytes(unsafe.Pointer(&p.privateKey), C.primes_num) 217 | } 218 | 219 | // FromBytes loads a PrivateKey from the given byte slice. 220 | func (p *PrivateKey) FromBytes(data []byte) error { 221 | if len(data) != PrivateKeySize { 222 | return ErrPrivateKeySize 223 | } 224 | 225 | p.privateKey = *((*C.private_key)(unsafe.Pointer(&data[0]))) 226 | return nil 227 | } 228 | 229 | // Equal is a constant time comparison of the two private keys. 230 | func (p *PrivateKey) Equal(privateKey *PrivateKey) bool { 231 | return hmac.Equal(p.Bytes(), privateKey.Bytes()) 232 | } 233 | 234 | // ToPEM writes out the PrivateKey to a PEM block. 235 | func (p *PrivateKey) ToPEM() (*pem.Block, error) { 236 | keyType := Name() + " PRIVATE KEY" 237 | 238 | zeros := make([]byte, PrivateKeySize) 239 | if bytes.Equal(p.Bytes(), zeros) { 240 | return nil, fmt.Errorf("%s: attemted to serialize scrubbed key", 241 | Name()) 242 | } 243 | blk := &pem.Block{ 244 | Type: keyType, 245 | Bytes: p.Bytes(), 246 | } 247 | return blk, nil 248 | } 249 | 250 | // ToPEMFile writes out the PrivateKey to a PEM file at path f. 251 | func (p *PrivateKey) ToPEMFile(f string) error { 252 | blk, err := p.ToPEM() 253 | if err != nil { 254 | return err 255 | } 256 | return ioutil.WriteFile(f, pem.EncodeToMemory(blk), 0600) 257 | } 258 | 259 | // FromPEM reads the PrivateKey from a PEM byte slice. 260 | func (p *PrivateKey) FromPEM(pemBytes []byte) error { 261 | keyType := Name() + " PRIVATE KEY" 262 | 263 | blk, _ := pem.Decode(pemBytes) 264 | if blk == nil { 265 | return fmt.Errorf("%s: failed to decode PEM bytes", Name()) 266 | } 267 | if blk.Type != keyType { 268 | return ErrPEMKeyTypeMismatch(blk.Type, keyType) 269 | } 270 | return p.FromBytes(blk.Bytes) 271 | } 272 | 273 | // FromPEMFile reads the PrivateKey from a PEM file at path f. 274 | func (p *PrivateKey) FromPEMFile(f string) error { 275 | buf, err := ioutil.ReadFile(f) 276 | if err != nil { 277 | return err 278 | } 279 | err = p.FromPEM(buf) 280 | if err != nil { 281 | return fmt.Errorf("%s in file %s", err.Error(), f) 282 | } 283 | return nil 284 | } 285 | 286 | // PublicKey returns the public key associated 287 | // with the given private key. 288 | func (p *PrivateKey) PublicKey() *PublicKey { 289 | return DerivePublicKey(p) 290 | } 291 | 292 | // DerivePublicKey derives a public key given a private key. 293 | func DerivePublicKey(privKey *PrivateKey) *PublicKey { 294 | var base C.public_key 295 | baseKey := new(PublicKey) 296 | baseKey.publicKey = base 297 | return groupAction(privKey, baseKey) 298 | } 299 | 300 | // GenerateKeyPair generates a new private and then 301 | // attempts to compute the public key. 302 | func GenerateKeyPair() (*PrivateKey, *PublicKey) { 303 | privKey := new(PrivateKey) 304 | C.csidh_private(&privKey.privateKey) 305 | return privKey, DerivePublicKey(privKey) 306 | } 307 | 308 | func groupAction(privateKey *PrivateKey, publicKey *PublicKey) *PublicKey { 309 | sharedKey := new(PublicKey) 310 | ok := C.csidh(&sharedKey.publicKey, &publicKey.publicKey, &privateKey.privateKey) 311 | if !ok { 312 | panic(ErrCTIDH) 313 | } 314 | return sharedKey 315 | } 316 | 317 | // DeriveSecret derives a shared secret. 318 | func DeriveSecret(privateKey *PrivateKey, publicKey *PublicKey) []byte { 319 | sharedSecret := groupAction(privateKey, publicKey) 320 | return sharedSecret.Bytes() 321 | } 322 | 323 | // Blind performs a blinding operation returning the blinded public key. 324 | // 325 | // WARNING: 326 | // Currently this blinding operation is not performed correctly 327 | // because the blindingFactor is not a valid CTIDH private key. 328 | // In order to fix this we need to be able to use the blinding 329 | // factor as a seed for deterministically generating the CTIDH private key 330 | // which participates in the group action operation. 331 | // This will require a change to the high-ctidh library. 332 | func Blind(blindingFactor []byte, publicKey *PublicKey) (*PublicKey, error) { 333 | if len(blindingFactor) != PrivateKeySize { 334 | return nil, ErrBlindDataSizeInvalid 335 | } 336 | 337 | privKey := new(PrivateKey) 338 | err := privKey.FromBytes(blindingFactor) 339 | if err != nil { 340 | return nil, err 341 | } 342 | return groupAction(privKey, publicKey), nil 343 | } 344 | 345 | // Name returns the string naming of the current 346 | // CTIDH that this binding is being used with; 347 | // Valid values are: 348 | // 349 | // CTIDH-511, CTIDH-512, CTIDH-1024 and, CTIDH-2048. 350 | func Name() string { 351 | return fmt.Sprintf("CTIDH-%d", C.BITS) 352 | } 353 | 354 | func validateBitSize(bits int) { 355 | switch bits { 356 | case 511: 357 | case 512: 358 | case 1024: 359 | case 2048: 360 | default: 361 | panic("CTIDH/cgo: BITS must be 511 or 512 or 1024 or 2048") 362 | } 363 | } 364 | 365 | func init() { 366 | validateBitSize(C.BITS) 367 | PrivateKeySize = C.primes_num 368 | switch C.BITS { 369 | case 511: 370 | PublicKeySize = 64 371 | case 512: 372 | PublicKeySize = 64 373 | case 1024: 374 | PublicKeySize = 128 375 | case 2048: 376 | PublicKeySize = 256 377 | } 378 | } 379 | -------------------------------------------------------------------------------- /autogen-memoized.patch: -------------------------------------------------------------------------------- 1 | diff --git a/autogen b/autogen 2 | index b422515..8fa1c26 100755 3 | --- a/autogen 4 | +++ b/autogen 5 | @@ -292,16 +292,22 @@ for bits,primes,batchsize,batchbound in data: 6 | f.write('.global uintbig_1\n') 7 | f.write('uintbig_1:\n') 8 | writeconst(f,1,plimbs) 9 | + f.write(' .size uintbig_1, %d\n' % pbytes) 10 | + f.write(' .type uintbig_1, @object\n') 11 | f.write('\n') 12 | 13 | f.write('.global uintbig_p\n') 14 | f.write('uintbig_p:\n') 15 | writeconst(f,p,plimbs) 16 | + f.write(' .size uintbig_p, %d\n' % pbytes) 17 | + f.write(' .type uintbig_p, @object\n') 18 | f.write('\n') 19 | 20 | f.write('.global uintbig_four_sqrt_p\n') 21 | f.write('uintbig_four_sqrt_p:\n') 22 | writeconst(f,sqrt16p,plimbs) 23 | + f.write(' .size uintbig_four_sqrt_p, %d\n' % pbytes) 24 | + f.write(' .type uintbig_four_sqrt_p, @object\n') 25 | f.write('\n') 26 | 27 | f.write('.section .text\n') 28 | @@ -398,6 +404,10 @@ for bits,primes,batchsize,batchbound in data: 29 | f.write('.set pbytes,%d\n' % pbytes) 30 | f.write('.set plimbs,%d\n' % plimbs) 31 | 32 | + f.write('.uintbig_p_local:\n') 33 | + writeconst(f,p,plimbs) 34 | + f.write('\n') 35 | + 36 | f.write('.inv_min_p_mod_r: /* -p^-1 mod 2^64 */\n') 37 | writeconst(f,inv,1) 38 | f.write('\n') 39 | @@ -405,16 +415,22 @@ for bits,primes,batchsize,batchbound in data: 40 | f.write('.global fp_0\n') 41 | f.write('fp_0:\n') 42 | f.write(' .zero %d\n' % pbytes) 43 | + f.write(' .size fp_0, %d\n' % pbytes) 44 | + f.write(' .type fp_0, @object\n') 45 | f.write('\n') 46 | 47 | f.write('.global fp_1\n') 48 | f.write('fp_1: /* 2^%d mod p */\n' % pmontbits) 49 | writeconst(f,(1<