github.com/cloudflare/circl@v1.5.0/dh/sidh/sidh_test.go (about)

     1  package sidh
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"encoding/hex"
     7  	"fmt"
     8  	"math/big"
     9  	"testing"
    10  
    11  	"github.com/cloudflare/circl/dh/sidh/internal/common"
    12  	. "github.com/cloudflare/circl/internal/test"
    13  )
    14  
    15  /* -------------------------------------------------------------------------
    16     Test data
    17     -------------------------------------------------------------------------*/
    18  
    19  type sidhVec struct {
    20  	id   uint8
    21  	name string
    22  	PkA  string
    23  	PrA  string
    24  	PkB  string
    25  	PrB  string
    26  }
    27  
    28  var tdataSidh = map[uint8]sidhVec{
    29  	Fp434: {
    30  		id:   Fp434,
    31  		name: "P-434",
    32  		PrA:  "3A727E04EA9B7E2A766A6F846489E7E7B915263BCEED308BB10FC900",
    33  		PrB:  "E37BFE55B43B32448F375903D8D226EC94ADBFEA1D2B3536EB987001",
    34  		PkA: "9E668D1E6750ED4B91EE052C32839CA9DD2E56D52BC24DECC950AAAD" +
    35  			"24CEED3F9049C77FE80F0B9B01E7F8DAD7833EEC2286544D6380009C" +
    36  			"379CDD3E7517CEF5E20EB01F8231D52FC30DC61D2F63FB357F85DC63" +
    37  			"96E8A95DB9740BD3A972C8DB7901B31F074CD3E45345CA78F9008171" +
    38  			"30E688A29A7CF0073B5C00FF2C65FBE776918EF9BD8E75B29EF7FAB7" +
    39  			"91969B60B0C5B37A8992EDEF95FA7BAC40A95DAFE02E237301FEE9A7" +
    40  			"A43FD0B73477E8035DD12B73FAFEF18D39904DDE3653A754F36BE188" +
    41  			"8F6607C6A7951349A414352CF31A29F2C40302DB406C48018C905EB9" +
    42  			"DC46AFBF42A9187A9BB9E51B587622A2862DC7D5CC598BF38ED6320F" +
    43  			"B51D8697AD3D7A72ABCC32A393F0133DA8DF5E253D9E00B760B2DF34" +
    44  			"2FCE974DCFE946CFE4727783531882800F9E5DD594D6D5A6275EEFEF" +
    45  			"9713ED838F4A06BB34D7B8D46E0B385AAEA1C7963601",
    46  		PkB: "C9F73E4497AAA3FDF9EB688135866A8A83934BA10E273B8CC3808CF0" +
    47  			"C1F5FAB3E9BB295885881B73DEBC875670C0F51C4BB40DF5FEDE01B8" +
    48  			"AF32D1BF10508B8C17B2734EB93B2B7F5D84A4A0F2F816E9E2C32AC2" +
    49  			"53C0B6025B124D05A87A9E2A8567930F44BAA14219B941B6B400B4AE" +
    50  			"D1D796DA12A5A9F0B8F3F5EE9DD43F64CB24A3B1719DF278ADF56B5F" +
    51  			"3395187829DA2319DEABF6BBD6EDA244DE2B62CC5AC250C1009DD1CD" +
    52  			"4712B0B37406612AD002B5E51A62B51AC9C0374D143ABBBD58275FAF" +
    53  			"C4A5E959C54838C2D6D9FB43B7B2609061267B6A2E6C6D01D295C422" +
    54  			"3E0D3D7A4CDCFB28A7818A737935279751A6DD8290FD498D1F6AD5F4" +
    55  			"FFF6BDFA536713F509DCE8047252F1E7D0DD9FCC414C0070B5DCCE36" +
    56  			"65A21A032D7FBE749181032183AFAD240B7E671E87FBBEC3A8CA4C11" +
    57  			"AA7A9A23AC69AE2ACF54B664DECD27753D63508F1B02",
    58  	},
    59  	Fp503: {
    60  		id:   Fp503,
    61  		name: "P-503",
    62  		PrA:  "D5B94224FA1AD1701EC277FDA83462D09E87181C2E583C5F09FD446A43F25103",
    63  		PrB:  "FF0EF91753D71D83D912656856086007AD2CF3B2A979B2BD63E5313BFD276506",
    64  		PkA: "FFB9A589DBB3975A20373F1AD3B449880E1DA47916FCD7C751A019AAA8E95A03" +
    65  			"4ADA1AE8BFCF6FBF70F323713318E25315DE865B29C9124982594BF78CD61C09" +
    66  			"B98C22307DFD4FC0958C58EC0D144828006E510FA4072D721B48D1A3CFEA02F6" +
    67  			"062324FE1B68F457CF29BD4EB1FB68D0684EE69F53A3FAC327404341BB39365B" +
    68  			"5DE885034C9A6DD6798CB08126183C696D0302730D489584AC8D6BCADF3AB4DE" +
    69  			"FFC227D3B1701462DA15BF68EF2B07C44712DB5429B74063202F43DC0EA7919D" +
    70  			"B95025B2B03E5A3EBF57FF37E21838CE8F5531F491315E576A260DC2F515DDF2" +
    71  			"4DEDE54CA69737CE6442B4219CD472D9CCCF8AF12B5C5B23ACB9C22929924ABA" +
    72  			"52C820932C82435518B920AFC43F2041263AE98D29E58B73F33A5DD42AAC7533" +
    73  			"404B4AC2B83DD2C7BEA7676930B6007CC185C264672B75F5332C18429BBC7B0F" +
    74  			"2EA3F746995A298E7443FFB0C1B27DCA7D19635064AF3B87938960587F56B724" +
    75  			"C1EF1FF012B056D7301F8713295B7734563542D4259B8BEA260C",
    76  		PkB: "AA3303F79FCE4855DE125B239D10BEC3B7082E55B08C769A9765F1BF41A31210" +
    77  			"66382D6BF2857D85138CC17D69593B8FC7703D22C553FB077DFB3AC577CF1E55" +
    78  			"2AED6DC0368123E01DDD70059A47E31E06423D2F697A3DA5D621EB5FF2A52EE7" +
    79  			"CA7D3BD01B427AC14CB6099E03C6639A3BAC9B939297CEB10F276F93CF16A1EE" +
    80  			"1B8085DE3DA037C911491B145B034A47B42A996A61C2313FEF166FD3665B0AE8" +
    81  			"C201A268DA01AB52E4759ACCC1DD09685A17CDA5D44AF847931ABB221D62E241" +
    82  			"2329394445ADFD662C77472A9268F40AB540177C0E6F1D59026E595C46FBED2F" +
    83  			"703838C5F3D7A811B500237596C5E960AA1F2989C5F17DD60D8A752569DBF250" +
    84  			"E01C63C9790D014CE05A9D8683814A320E30185E478AF9ABD761DADDA8DE7E3E" +
    85  			"A53C224AC8313C176D14BD0F04AB09A9D0D0302ACBF768EB4DB03681EAE3BC10" +
    86  			"21CAA429A1490AE1D6E0CA9D6BC4BCD14B1CFE694226D03E8731E9E0B3760877" +
    87  			"7D56630B31298CC05B6FF6C1A08935312D8E95B8056AD7831A22",
    88  	},
    89  	Fp751: {
    90  		id:   Fp751,
    91  		name: "P-751",
    92  		// PrA - Alice's Private Key: 2*randint(0,2^371)
    93  		PrA: "B1937F2B009FD9F785C5AD899F5ED2FD064218C07A76798D1433336E093DF184CA0CAF6E7C92B320E89632A7765F0B",
    94  		// PrB - Bob's Private Key: 3*randint(0,3^238)
    95  		PrB: "54DB4380D4134E187F5793FA82A4F18B39CA2F8F1C145FFB040FC917E2F41542037FF227F3A4AAFB17A6983AA88B4403",
    96  		PkA: "2B53BB7C002A9D18B077D068C38353ADFD57A3CA0E431D92CCB8060D41A83A09" +
    97  			"C1500BEE63FB07DA1DBEDB4AF145F22C2D8152B07B7E124F06643C7AB5B1C48D" +
    98  			"581FC4C6FB7FC165F6E02F40B47D81400B84B6288DEAB38DE795B51486430974" +
    99  			"788377770D46B0ABC1F3F7C3647A0E38ACED475EA8EE990F3C5A7668452478C1" +
   100  			"975993E126B405E476AD6A10E9DD4E135ADA910BE41A8F93331268791F7B958A" +
   101  			"0888052D1CF7B9128058A258002F22AC48E2C296E3935033139D336FDEB33E9B" +
   102  			"8713663B1705B566AC4F4455FD0E710A5236C18011EA971DDD18633F9022C432" +
   103  			"B225EC401FCD4C233B8BF91BE5944D1A657516CE4B844D0BC6049478046B60B6" +
   104  			"BE163E41CCE743054806B13FAC0A1FA393C866D74A5A93A938209287324FAB46" +
   105  			"295F5B271C9D8CFEE17868599202D7AEF1A67EBE2FA2A27AD9E0991CEDEE270D" +
   106  			"1E7639425D94A0F0A2EFDE90B86D5D7F03F3CF97D30415CAA661F865ADB788E6" +
   107  			"3F79EE2FE8637D9DCAF3BCD5C42AE499688048BBB49F216B4714675FD87F7CCC" +
   108  			"37A0C2EA56BB53675584F7648BA052F963C35387ECC4DDED4F8076934FF32D5D" +
   109  			"77B5D3C57553757A4CB9588C4575D4CC4CA8280370041A6FF03007C31D0712E8" +
   110  			"327CC5BC9885F896904FAB4EE167745260D331C3E85E8A32FCCD23093F2C55A9" +
   111  			"EA8D7BECEFC3564D3C3D4CE585B62785773B2228742185C97D6F51CD3E3CF885" +
   112  			"5CF37F305734E97A86479580FDB9983DDCAE9D0F1B125523DB2FE58339240A58" +
   113  			"131D0EFD14A560A6F7EDE774F6C3C54F46DD0830",
   114  		PkB: "E93E4E2B0E7348C088FD91F8E3B17CC52B55C5E8933B6D00B3757E5347C5A0AE" +
   115  			"5F1A6051C32FB20A41013A244484C8D0501B6A3516A634581E08C907F29D651C" +
   116  			"BCC5B6CA6BAC4DCC980CD36155B60A2108134D3F78ED19ADA2B8B20184302FD7" +
   117  			"47E096B01ABB33CB76B115D673B00F76913281CF7A0B44FF5CF1A256B8138FE6" +
   118  			"77AB8D22FEBBCB10EB46E442D0AD96A126DD24E941280C7AB3F9FAC2832A149C" +
   119  			"AD93D221EDCB406303F5A1B38F43F310244D766239A7F4D89EED4C6FD272BC4F" +
   120  			"F7C4E34F3E5E77BFF59D6FE5C0D3937F574ABE81C2FC1FEDD98F43323F8F2D7C" +
   121  			"154DCEBF410FCF698A4E6506D6FD6E4A861395F75698C810A527E00ADC118C90" +
   122  			"9CDE7729B24C6E7DE9C92CFB592CB9A4BAC54DB468AA52724452CC7A7B40509B" +
   123  			"B7894ACCF2C7933537FD52DB312D7FBC4FDE01AC2350CD25ABDD5E6F3AEF87BA" +
   124  			"1BE23691544EB6A4F8FA9CF2BE70B9665EA479B44DC3C61D4651CDDB53656B6F" +
   125  			"3A2D139EC6BE8550B8A623CCA30EB5374F70C67A932712002006F3D73190384F" +
   126  			"6D3BEC9DB9F46E9B7AE2891E615752E74DC112579CF43283E8B6EBEF4C802BD6" +
   127  			"700A97B9739E8694B48D8CB9C8ABBC915A834FF1DBF2C823B3E156D0A415C558" +
   128  			"71B719BD9DD215F57C8D19A6B4F8CD93283D6EBD135347DAAF4F20C54D24017F" +
   129  			"5E6AF400AB6DC98AD2D5810E59360DF64503599FAF6FBAB720CC557DEEF0F528" +
   130  			"249DEB530C8F310465E0BE2B4041C24DAF783BC4EE71D27C760FA7CFD4A9A691" +
   131  			"70BCBA465CA242961671DF0C53A8112CCD708D58",
   132  	},
   133  }
   134  
   135  /* -------------------------------------------------------------------------
   136     Helpers
   137     -------------------------------------------------------------------------*/
   138  // Converts string to private key.
   139  func convToPrv(s string, v KeyVariant, id uint8) *PrivateKey {
   140  	key := NewPrivateKey(id, v)
   141  	hex, e := hex.DecodeString(s)
   142  	if e != nil {
   143  		panic("non-hex number provided")
   144  	}
   145  	e = key.Import(hex)
   146  	if e != nil {
   147  		panic("Can't import private key")
   148  	}
   149  	return key
   150  }
   151  
   152  // Converts string to public key.
   153  func convToPub(s string, v KeyVariant, id uint8) *PublicKey {
   154  	key := NewPublicKey(id, v)
   155  	hex, e := hex.DecodeString(s)
   156  	if e != nil {
   157  		panic("non-hex number provided")
   158  	}
   159  	e = key.Import(hex)
   160  	if e != nil {
   161  		panic("Can't import public key")
   162  	}
   163  	return key
   164  }
   165  
   166  /* Unit tests */
   167  
   168  func testKeygen(t *testing.T, v sidhVec) {
   169  	pubA := NewPublicKey(v.id, KeyVariantSidhA)
   170  	pubB := NewPublicKey(v.id, KeyVariantSidhB)
   171  	alicePrivate := convToPrv(v.PrA, KeyVariantSidhA, v.id)
   172  	bobPrivate := convToPrv(v.PrB, KeyVariantSidhB, v.id)
   173  	expPubA := convToPub(v.PkA, KeyVariantSidhA, v.id)
   174  	expPubB := convToPub(v.PkB, KeyVariantSidhB, v.id)
   175  
   176  	alicePrivate.GeneratePublicKey(pubA)
   177  	bobPrivate.GeneratePublicKey(pubB)
   178  
   179  	got := make([]byte, expPubA.Size())
   180  	exp := make([]byte, expPubA.Size())
   181  	pubA.Export(got)
   182  	expPubA.Export(exp)
   183  	if !bytes.Equal(got, exp) {
   184  		t.Fatalf("unexpected value of public key A\ngot [%X]\nexp [%X]", got, exp)
   185  	}
   186  
   187  	got = make([]byte, expPubB.Size())
   188  	exp = make([]byte, expPubB.Size())
   189  	pubB.Export(got)
   190  	expPubB.Export(exp)
   191  	if !bytes.Equal(got, exp) {
   192  		t.Fatalf("unexpected value of public key B\ngot [%X]\nexp [%X]", got, exp)
   193  	}
   194  }
   195  
   196  func testRoundtrip(t *testing.T, v sidhVec) {
   197  	var err error
   198  	pubA := NewPublicKey(v.id, KeyVariantSidhA)
   199  	pubB := NewPublicKey(v.id, KeyVariantSidhB)
   200  	prvA := NewPrivateKey(v.id, KeyVariantSidhA)
   201  	prvB := NewPrivateKey(v.id, KeyVariantSidhB)
   202  	s1 := make([]byte, common.Params(v.id).SharedSecretSize)
   203  	s2 := make([]byte, common.Params(v.id).SharedSecretSize)
   204  
   205  	// Generate private keys
   206  	err = prvA.Generate(rand.Reader)
   207  	CheckNoErr(t, err, "key generation failed")
   208  	err = prvB.Generate(rand.Reader)
   209  	CheckNoErr(t, err, "key generation failed")
   210  
   211  	// Generate public keys
   212  	prvA.GeneratePublicKey(pubA)
   213  	prvB.GeneratePublicKey(pubB)
   214  
   215  	// Derive shared secret
   216  	prvB.DeriveSecret(s1, pubA)
   217  	prvA.DeriveSecret(s2, pubB)
   218  
   219  	if !bytes.Equal(s1[:], s2[:]) {
   220  		t.Fatalf("Two shared keys do not match:\ns1 [%X]\ns2 [%X]", s1, s2)
   221  	}
   222  }
   223  
   224  func testKeyAgreement(t *testing.T, v sidhVec) {
   225  	var err error
   226  	s1 := make([]byte, common.Params(v.id).SharedSecretSize)
   227  	s2 := make([]byte, common.Params(v.id).SharedSecretSize)
   228  
   229  	// KeyPairs
   230  	alicePublic := convToPub(v.PkA, KeyVariantSidhA, v.id)
   231  	bobPublic := convToPub(v.PkB, KeyVariantSidhB, v.id)
   232  	alicePrivate := convToPrv(v.PrA, KeyVariantSidhA, v.id)
   233  	bobPrivate := convToPrv(v.PrB, KeyVariantSidhB, v.id)
   234  
   235  	// Do actual test
   236  	bobPrivate.DeriveSecret(s1, alicePublic)
   237  	alicePrivate.DeriveSecret(s2, bobPublic)
   238  
   239  	if !bytes.Equal(s1[:], s2[:]) {
   240  		t.Fatalf("two shared keys do not match\ngot [%X]\nexp [%X]", s1, s2)
   241  	}
   242  
   243  	// Negative case
   244  	dec, err := hex.DecodeString(v.PkA)
   245  	CheckNoErr(t, err, "decoding failed")
   246  
   247  	dec[0] = ^dec[0]
   248  	err = alicePublic.Import(dec)
   249  	CheckNoErr(t, err, "import failed")
   250  	bobPrivate.DeriveSecret(s1, alicePublic)
   251  	alicePrivate.DeriveSecret(s2, bobPublic)
   252  	if bytes.Equal(s1[:], s2[:]) {
   253  		t.Fatalf("DeriveSecret produces wrong results. The two shared keys match, but they shouldn't")
   254  	}
   255  }
   256  
   257  func testImportExport(t *testing.T, v sidhVec) {
   258  	var err error
   259  	a := NewPublicKey(v.id, KeyVariantSidhA)
   260  	b := NewPublicKey(v.id, KeyVariantSidhB)
   261  
   262  	// Import keys
   263  	aHex, err := hex.DecodeString(v.PkA)
   264  	CheckNoErr(t, err, "invalid hex-number provided")
   265  
   266  	err = a.Import(aHex)
   267  	CheckNoErr(t, err, "import failed")
   268  
   269  	bHex, err := hex.DecodeString(v.PkB)
   270  	CheckNoErr(t, err, "invalid hex-number provided")
   271  
   272  	err = b.Import(bHex)
   273  	CheckNoErr(t, err, "import failed")
   274  
   275  	aBytes := make([]byte, a.Size())
   276  	bBytes := make([]byte, b.Size())
   277  	a.Export(aBytes)
   278  	b.Export(bBytes)
   279  
   280  	// Export and check if same
   281  	if !bytes.Equal(bBytes, bHex) || !bytes.Equal(aBytes, aHex) {
   282  		t.Fatalf("export/import failed")
   283  	}
   284  
   285  	if (len(bBytes) != b.Size()) || (len(aBytes) != a.Size()) {
   286  		t.Fatalf("wrong size of exported keys")
   287  	}
   288  
   289  	// Ensure that public key is unchanged after it is exported
   290  	aBytes2 := make([]byte, a.Size())
   291  	bBytes2 := make([]byte, b.Size())
   292  	a.Export(aBytes2)
   293  	b.Export(bBytes2)
   294  	if !bytes.Equal(aBytes, aBytes2) || !bytes.Equal(bBytes, bBytes2) {
   295  		t.Fatalf("Second export doesn't match first export")
   296  	}
   297  }
   298  
   299  func testPrivateKeyBelowMax(t *testing.T, vec sidhVec) {
   300  	for variant, keySz := range map[KeyVariant]*common.DomainParams{
   301  		KeyVariantSidhA: &common.Params(vec.id).A,
   302  		KeyVariantSidhB: &common.Params(vec.id).B,
   303  	} {
   304  		func(v KeyVariant, dp *common.DomainParams) {
   305  			blen := int(dp.SecretByteLen)
   306  			prv := NewPrivateKey(vec.id, v)
   307  			secretBytes := make([]byte, prv.Size())
   308  
   309  			// Calculate either (2^e2 - 1) or (2^s - 1); where s=ceil(log_2(3^e3)))
   310  			maxSecretVal := big.NewInt(int64(dp.SecretBitLen))
   311  			maxSecretVal.Exp(big.NewInt(int64(2)), maxSecretVal, nil)
   312  			maxSecretVal.Sub(maxSecretVal, big.NewInt(1))
   313  
   314  			// Do same test 1000 times
   315  			for i := 0; i < 1000; i++ {
   316  				err := prv.Generate(rand.Reader)
   317  				CheckNoErr(t, err, "Private key generation")
   318  
   319  				// Convert to big-endian, as that's what expected by (*Int)SetBytes()
   320  				prv.Export(secretBytes)
   321  				for i := 0; i < blen/2; i++ {
   322  					tmp := secretBytes[i] ^ secretBytes[blen-i-1]
   323  					secretBytes[i] = tmp ^ secretBytes[i]
   324  					secretBytes[blen-i-1] = tmp ^ secretBytes[blen-i-1]
   325  				}
   326  				prvBig := new(big.Int).SetBytes(secretBytes)
   327  				// Check if generated key is bigger then acceptable
   328  				if prvBig.Cmp(maxSecretVal) == 1 {
   329  					t.Error("Generated private key is wrong")
   330  				}
   331  			}
   332  		}(variant, keySz)
   333  	}
   334  }
   335  
   336  func TestKeyAgreementP751_AliceEvenNumber(t *testing.T) {
   337  	// even alice
   338  	v := tdataSidh[Fp751]
   339  	v.PkA = "FDED78E9F490CB518BD6357E18FEEB63FFEFEBE907338B3ABCA74A7E590DBF79" +
   340  		"0C732AB9E3778244608CD563064BDF6AAEF511CEAF07C702309ADAA7EBEBC6B3" +
   341  		"D7B00F5C02FB2FEDA763B2D695FD27F93F45D3AC58C2F0524A942D6DE407B651" +
   342  		"1854A1D974F11A8686CF8AD675A081F4B668F3C6617029AA33FD597C8910AB37" +
   343  		"F71DBE004A3FF8442C4B65DE51201DFAE6F9DC20FDE5B998D19C23589437229D" +
   344  		"724B4378602321F247276E7B4E441383C9BE6D277A127362D9C9FB68A41C5F5B" +
   345  		"9D2BA63FA790D62315DECF5049F0476A43D30BC1E8A36047C8EE0DA9E0A3937E" +
   346  		"BDF52A91BC53266A82CBF2CEAB227CB6D5075B486679CA7701F6F35C53499B45" +
   347  		"A451CE37C57B9BB1276142F495B83D987BD4B62E78E3084DCF3EB906D19DFA8F" +
   348  		"819DFC7FDF104C1A01CCF8D933B91EBD72CDE83A502B1FB0A5DF782BC7085766" +
   349  		"AE795123903A2D30F0F79073D27CF71BA4C9D3CA86512842AA8B5AEB729C78B1" +
   350  		"E15392E20A6043C05F88F6F412C3C9FE14F8FAAE8B8482514822162F93E81615" +
   351  		"BDD77363F872D0506FFDC1809C165A5C8A19F8EA0254D73E08202A6FF3AF43CF" +
   352  		"A7EC9B137AE003A19440DCE2EF3CFC99080F75E683AF6D0E25DF55C60B2A8013" +
   353  		"FA3D59828D31C2360DF83E202FB48AFAA65AF7279137E827B80E761FA49B842A" +
   354  		"A70FD4E77B284A14B8E28C8B11B389E1160DD9877C8D5A5A1471E605F1848369" +
   355  		"3F7578B3733DDEE117227E35B1765FEBB765B340A084E8D99176C0837099C864" +
   356  		"C71C864842D3E9B58CB870AD45F3B6BE476FEB6D"
   357  	v.PrA = "C09957CC83045FB4C3726384D784476ACB6FFD92E5B15B3C2D451BA063F1BD4CE" +
   358  		"D8FBCF682A98DD0954D37BCAF730F"
   359  	testKeyAgreement(t, v)
   360  }
   361  
   362  /* -------------------------------------------------------------------------
   363     Wrappers for 'testing' SIDH
   364     -------------------------------------------------------------------------*/
   365  
   366  func testSidhVec(t *testing.T, m *map[uint8]sidhVec, f func(t *testing.T, v sidhVec)) {
   367  	for i := range *m {
   368  		v := (*m)[i]
   369  		t.Run(v.name, func(t *testing.T) { f(t, v) })
   370  	}
   371  }
   372  func TestKeygen(t *testing.T)             { testSidhVec(t, &tdataSidh, testKeygen) }
   373  func TestRoundtrip(t *testing.T)          { testSidhVec(t, &tdataSidh, testRoundtrip) }
   374  func TestImportExport(t *testing.T)       { testSidhVec(t, &tdataSidh, testImportExport) }
   375  func TestKeyAgreement(t *testing.T)       { testSidhVec(t, &tdataSidh, testKeyAgreement) }
   376  func TestPrivateKeyBelowMax(t *testing.T) { testSidhVec(t, &tdataSidh, testPrivateKeyBelowMax) }
   377  
   378  /* -------------------------------------------------------------------------
   379     Benchmarking
   380     -------------------------------------------------------------------------*/
   381  
   382  func BenchmarkSidhKeyAgreementP751(b *testing.B) {
   383  	// KeyPairs
   384  	alicePublic := convToPub(tdataSidh[Fp751].PkA, KeyVariantSidhA, Fp751)
   385  	bobPublic := convToPub(tdataSidh[Fp751].PkB, KeyVariantSidhB, Fp751)
   386  	alicePrivate := convToPrv(tdataSidh[Fp751].PrA, KeyVariantSidhA, Fp751)
   387  	bobPrivate := convToPrv(tdataSidh[Fp751].PrB, KeyVariantSidhB, Fp751)
   388  	var ss [2 * 94]byte
   389  
   390  	for i := 0; i < b.N; i++ {
   391  		// Derive shared secret
   392  		bobPrivate.DeriveSecret(ss[:], alicePublic)
   393  		alicePrivate.DeriveSecret(ss[:], bobPublic)
   394  	}
   395  }
   396  
   397  func BenchmarkSidhKeyAgreementP503(b *testing.B) {
   398  	// KeyPairs
   399  	alicePublic := convToPub(tdataSidh[Fp503].PkA, KeyVariantSidhA, Fp503)
   400  	bobPublic := convToPub(tdataSidh[Fp503].PkB, KeyVariantSidhB, Fp503)
   401  	alicePrivate := convToPrv(tdataSidh[Fp503].PrA, KeyVariantSidhA, Fp503)
   402  	bobPrivate := convToPrv(tdataSidh[Fp503].PrB, KeyVariantSidhB, Fp503)
   403  	var ss [2 * 63]byte
   404  
   405  	for i := 0; i < b.N; i++ {
   406  		// Derive shared secret
   407  		bobPrivate.DeriveSecret(ss[:], alicePublic)
   408  		alicePrivate.DeriveSecret(ss[:], bobPublic)
   409  	}
   410  }
   411  
   412  func BenchmarkSidhKeyAgreementP434(b *testing.B) {
   413  	// KeyPairs
   414  	alicePublic := convToPub(tdataSidh[Fp434].PkA, KeyVariantSidhA, Fp434)
   415  	bobPublic := convToPub(tdataSidh[Fp434].PkB, KeyVariantSidhB, Fp434)
   416  	alicePrivate := convToPrv(tdataSidh[Fp434].PrA, KeyVariantSidhA, Fp434)
   417  	bobPrivate := convToPrv(tdataSidh[Fp434].PrB, KeyVariantSidhB, Fp434)
   418  	var ss [2 * 63]byte
   419  
   420  	for i := 0; i < b.N; i++ {
   421  		// Derive shared secret
   422  		bobPrivate.DeriveSecret(ss[:], alicePublic)
   423  		alicePrivate.DeriveSecret(ss[:], bobPublic)
   424  	}
   425  }
   426  
   427  func BenchmarkAliceKeyGenPrvP751(b *testing.B) {
   428  	prv := NewPrivateKey(Fp751, KeyVariantSidhA)
   429  	for n := 0; n < b.N; n++ {
   430  		_ = prv.Generate(rand.Reader)
   431  	}
   432  }
   433  
   434  func BenchmarkAliceKeyGenPrvP503(b *testing.B) {
   435  	prv := NewPrivateKey(Fp503, KeyVariantSidhA)
   436  	for n := 0; n < b.N; n++ {
   437  		_ = prv.Generate(rand.Reader)
   438  	}
   439  }
   440  
   441  func BenchmarkAliceKeyGenPrvP434(b *testing.B) {
   442  	prv := NewPrivateKey(Fp434, KeyVariantSidhA)
   443  	for n := 0; n < b.N; n++ {
   444  		_ = prv.Generate(rand.Reader)
   445  	}
   446  }
   447  
   448  func BenchmarkBobKeyGenPrvP751(b *testing.B) {
   449  	prv := NewPrivateKey(Fp751, KeyVariantSidhB)
   450  	for n := 0; n < b.N; n++ {
   451  		_ = prv.Generate(rand.Reader)
   452  	}
   453  }
   454  
   455  func BenchmarkBobKeyGenPrvP503(b *testing.B) {
   456  	prv := NewPrivateKey(Fp503, KeyVariantSidhB)
   457  	for n := 0; n < b.N; n++ {
   458  		_ = prv.Generate(rand.Reader)
   459  	}
   460  }
   461  
   462  func BenchmarkBobKeyGenPrvP434(b *testing.B) {
   463  	prv := NewPrivateKey(Fp434, KeyVariantSidhB)
   464  	for n := 0; n < b.N; n++ {
   465  		_ = prv.Generate(rand.Reader)
   466  	}
   467  }
   468  
   469  func BenchmarkAliceKeyGenPubP751(b *testing.B) {
   470  	prv := NewPrivateKey(Fp751, KeyVariantSidhA)
   471  	pub := NewPublicKey(Fp751, KeyVariantSidhA)
   472  	_ = prv.Generate(rand.Reader)
   473  	for n := 0; n < b.N; n++ {
   474  		prv.GeneratePublicKey(pub)
   475  	}
   476  }
   477  
   478  func BenchmarkAliceKeyGenPubP503(b *testing.B) {
   479  	prv := NewPrivateKey(Fp503, KeyVariantSidhA)
   480  	pub := NewPublicKey(Fp503, KeyVariantSidhA)
   481  	_ = prv.Generate(rand.Reader)
   482  	for n := 0; n < b.N; n++ {
   483  		prv.GeneratePublicKey(pub)
   484  	}
   485  }
   486  
   487  func BenchmarkAliceKeyGenPubP434(b *testing.B) {
   488  	prv := NewPrivateKey(Fp434, KeyVariantSidhA)
   489  	pub := NewPublicKey(Fp434, KeyVariantSidhA)
   490  	_ = prv.Generate(rand.Reader)
   491  	for n := 0; n < b.N; n++ {
   492  		prv.GeneratePublicKey(pub)
   493  	}
   494  }
   495  
   496  func BenchmarkBobKeyGenPubP751(b *testing.B) {
   497  	prv := NewPrivateKey(Fp751, KeyVariantSidhB)
   498  	pub := NewPublicKey(Fp751, KeyVariantSidhB)
   499  	_ = prv.Generate(rand.Reader)
   500  	for n := 0; n < b.N; n++ {
   501  		prv.GeneratePublicKey(pub)
   502  	}
   503  }
   504  
   505  func BenchmarkBobKeyGenPubP503(b *testing.B) {
   506  	prv := NewPrivateKey(Fp503, KeyVariantSidhB)
   507  	pub := NewPublicKey(Fp503, KeyVariantSidhB)
   508  	_ = prv.Generate(rand.Reader)
   509  	for n := 0; n < b.N; n++ {
   510  		prv.GeneratePublicKey(pub)
   511  	}
   512  }
   513  
   514  func BenchmarkBobKeyGenPubP434(b *testing.B) {
   515  	prv := NewPrivateKey(Fp434, KeyVariantSidhB)
   516  	pub := NewPublicKey(Fp434, KeyVariantSidhB)
   517  	_ = prv.Generate(rand.Reader)
   518  	for n := 0; n < b.N; n++ {
   519  		prv.GeneratePublicKey(pub)
   520  	}
   521  }
   522  
   523  func BenchmarkSharedSecretAliceP751(b *testing.B) {
   524  	aPr := convToPrv(tdataSidh[Fp751].PrA, KeyVariantSidhA, Fp751)
   525  	bPk := convToPub(tdataSidh[Fp751].PkB, KeyVariantSidhB, Fp751)
   526  	var ss [2 * 94]byte
   527  	for n := 0; n < b.N; n++ {
   528  		aPr.DeriveSecret(ss[:], bPk)
   529  	}
   530  }
   531  
   532  func BenchmarkSharedSecretAliceP503(b *testing.B) {
   533  	aPr := convToPrv(tdataSidh[Fp503].PrA, KeyVariantSidhA, Fp503)
   534  	bPk := convToPub(tdataSidh[Fp503].PkB, KeyVariantSidhB, Fp503)
   535  	var ss [2 * 63]byte
   536  	for n := 0; n < b.N; n++ {
   537  		aPr.DeriveSecret(ss[:], bPk)
   538  	}
   539  }
   540  
   541  func BenchmarkSharedSecretAliceP434(b *testing.B) {
   542  	aPr := convToPrv(tdataSidh[Fp434].PrA, KeyVariantSidhA, Fp434)
   543  	bPk := convToPub(tdataSidh[Fp434].PkB, KeyVariantSidhB, Fp434)
   544  	var ss [2 * 63]byte
   545  	for n := 0; n < b.N; n++ {
   546  		aPr.DeriveSecret(ss[:], bPk)
   547  	}
   548  }
   549  
   550  func BenchmarkSharedSecretBobP751(b *testing.B) {
   551  	// m_B = 3*randint(0,3^238)
   552  	aPk := convToPub(tdataSidh[Fp751].PkA, KeyVariantSidhA, Fp751)
   553  	bPr := convToPrv(tdataSidh[Fp751].PrB, KeyVariantSidhB, Fp751)
   554  	var ss [2 * 94]byte
   555  	for n := 0; n < b.N; n++ {
   556  		bPr.DeriveSecret(ss[:], aPk)
   557  	}
   558  }
   559  
   560  func BenchmarkSharedSecretBobP503(b *testing.B) {
   561  	// m_B = 3*randint(0,3^238)
   562  	aPk := convToPub(tdataSidh[Fp503].PkA, KeyVariantSidhA, Fp503)
   563  	bPr := convToPrv(tdataSidh[Fp503].PrB, KeyVariantSidhB, Fp503)
   564  	var ss [2 * 63]byte
   565  	for n := 0; n < b.N; n++ {
   566  		bPr.DeriveSecret(ss[:], aPk)
   567  	}
   568  }
   569  
   570  func BenchmarkSharedSecretBobP434(b *testing.B) {
   571  	// m_B = 3*randint(0,3^238)
   572  	aPk := convToPub(tdataSidh[Fp434].PkA, KeyVariantSidhA, Fp434)
   573  	bPr := convToPrv(tdataSidh[Fp434].PrB, KeyVariantSidhB, Fp434)
   574  	var ss [2 * 63]byte
   575  	for n := 0; n < b.N; n++ {
   576  		bPr.DeriveSecret(ss[:], aPk)
   577  	}
   578  }
   579  
   580  // Examples
   581  
   582  func ExamplePrivateKey() {
   583  	// import "github.com/cloudflare/circl/dh/sidh"
   584  
   585  	// Alice's key pair
   586  	prvA := NewPrivateKey(Fp503, KeyVariantSidhA)
   587  	pubA := NewPublicKey(Fp503, KeyVariantSidhA)
   588  	// Bob's key pair
   589  	prvB := NewPrivateKey(Fp503, KeyVariantSidhB)
   590  	pubB := NewPublicKey(Fp503, KeyVariantSidhB)
   591  	// Generate keypair for Alice
   592  	err := prvA.Generate(rand.Reader)
   593  	if err != nil {
   594  		fmt.Print(err)
   595  	}
   596  	prvA.GeneratePublicKey(pubA)
   597  	// Generate keypair for Bob
   598  	err = prvB.Generate(rand.Reader)
   599  	if err != nil {
   600  		fmt.Print(err)
   601  	}
   602  	prvB.GeneratePublicKey(pubB)
   603  	// Buffers storing shared secret
   604  	ssA := make([]byte, prvA.SharedSecretSize())
   605  	ssB := make([]byte, prvA.SharedSecretSize())
   606  	// Alice calculates shared secret with hers private
   607  	// key and Bob's public key
   608  	prvA.DeriveSecret(ssA[:], pubB)
   609  	// Bob calculates shared secret with hers private
   610  	// key and Alice's public key
   611  	prvB.DeriveSecret(ssB[:], pubA)
   612  	// Check if ssA == ssB
   613  	fmt.Printf("%t\n", bytes.Equal(ssA, ssB))
   614  	// Output:
   615  	// true
   616  }