| import 'dart:typed_data'; |
| |
| import 'package:pointycastle/pointycastle.dart'; |
| import 'package:pointycastle/src/utils.dart'; |
| import 'package:test/test.dart'; |
| |
| class ECDHTestvector { |
| final int index; |
| late final ECPrivateKey privateKey; |
| late final ECPublicKey publicKey; |
| late final BigInt Z; |
| |
| ECDHTestvector(this.index, String a, String bx, String by, String z, |
| ECDomainParameters ecDomainParameters) { |
| final curve = ecDomainParameters.curve; |
| privateKey = ECPrivateKey(BigInt.parse(a, radix: 16), ecDomainParameters); |
| publicKey = ECPublicKey( |
| curve.createPoint( |
| BigInt.parse(bx, radix: 16), BigInt.parse(by, radix: 16)), |
| ecDomainParameters); |
| Z = BigInt.parse(z, radix: 16); |
| } |
| } |
| |
| class P256Testvector extends ECDHTestvector { |
| P256Testvector(int index, String a, String bx, String by, String z) |
| : super(index, a, bx, by, z, ECDomainParameters('secp256r1')); |
| } |
| |
| class BrainpoolP256r1TestVector extends ECDHTestvector { |
| BrainpoolP256r1TestVector(int index, String a, String bx, String by, String z) |
| : super(index, a, bx, by, z, ECDomainParameters('brainpoolp256r1')); |
| } |
| |
| // From http://csrc.nist.gov/groups/STM/cavp/documents/components/ecccdhtestvectors.zip |
| final testVectors = <P256Testvector>[ |
| P256Testvector( |
| 1, |
| '07d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534', |
| '700C48F77F56584C5CC632CA65640DB91B6BACCE3A4DF6B42CE7CC838833D287', |
| 'DB71E509E3FD9B060DDB20BA5C51DCC5948D46FBF640DFE0441782CAB85FA4AC', |
| '46FC62106420FF012E54A434FBDD2D25CCC5852060561E68040DD7778997BD7B'), |
| P256Testvector( |
| 2, |
| '38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5', |
| '809F04289C64348C01515EB03D5CE7AC1A8CB9498F5CAA50197E58D43A86A7AE', |
| 'B29D84E811197F25EBA8F5194092CB6FF440E26D4421011372461F579271CDA3', |
| '057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67'), |
| P256Testvector( |
| 3, |
| '1accfaf1b97712b85a6f54b148985a1bdc4c9bec0bd258cad4b3d603f49f32c8', |
| 'A2339C12D4A03C33546DE533268B4AD667DEBF458B464D77443636440EE7FEC3', |
| 'EF48A3AB26E20220BCDA2C1851076839DAE88EAE962869A497BF73CB66FAF536', |
| '2D457B78B4614132477618A5B077965EC90730A8C81A1C75D6D4EC68005D67EC'), |
| P256Testvector( |
| 4, |
| '207c43a79bfee03db6f4b944f53d2fb76cc49ef1c9c4d34d51b6c65c4db6932d', |
| 'DF3989B9FA55495719B3CF46DCCD28B5153F7808191DD518EFF0C3CFF2B705ED', |
| '422294FF46003429D739A33206C8752552C8BA54A270DEFC06E221E0FEAF6AC4', |
| '96441259534B80F6AEE3D287A6BB17B5094DD4277D9E294F8FE73E48BF2A0024'), |
| P256Testvector( |
| 5, |
| '59137e38152350b195c9718d39673d519838055ad908dd4757152fd8255c09bf', |
| '41192D2813E79561E6A1D6F53C8BC1A433A199C835E141B05A74A97B0FAEB922', |
| '1AF98CC45E98A7E041B01CF35F462B7562281351C8EBF3FFA02E33A0722A1328', |
| '19D44C8D63E8E8DD12C22A87B8CD4ECE27ACDDE04DBF47F7F27537A6999A8E62'), |
| P256Testvector( |
| 6, |
| 'f5f8e0174610a661277979b58ce5c90fee6c9b3bb346a90a7196255e40b132ef', |
| '33E82092A0F1FB38F5649D5867FBA28B503172B7035574BF8E5B7100A3052792', |
| 'F2CF6B601E0A05945E335550BF648D782F46186C772C0F20D3CD0D6B8CA14B2F', |
| '664E45D5BBA4AC931CD65D52017E4BE9B19A515F669BEA4703542A2C525CD3D3'), |
| P256Testvector( |
| 7, |
| '3b589af7db03459c23068b64f63f28d3c3c6bc25b5bf76ac05f35482888b5190', |
| '6A9E0C3F916E4E315C91147BE571686D90464E8BF981D34A90B6353BCA6EEBA7', |
| '40F9BEAD39C2F2BCC2602F75B8A73EC7BDFFCBCEAD159D0174C6C4D3C5357F05', |
| 'CA342DAA50DC09D61BE7C196C85E60A80C5CB04931746820BE548CDDE055679D'), |
| P256Testvector( |
| 8, |
| 'd8bf929a20ea7436b2461b541a11c80e61d826c0a4c9d322b31dd54e7f58b9c8', |
| 'A9C0ACADE55C2A73EAD1A86FB0A9713223C82475791CD0E210B046412CE224BB', |
| 'F6DE0AFA20E93E078467C053D241903EDAD734C6B403BA758C2B5FF04C9D4229', |
| '35AA9B52536A461BFDE4E85FC756BE928C7DE97923F0416C7A3AC8F88B3D4489'), |
| P256Testvector( |
| 9, |
| '0f9883ba0ef32ee75ded0d8bda39a5146a29f1f2507b3bd458dbea0b2bb05b4d', |
| '94E94F16A98255FFF2B9AC0C9598AAC35487B3232D3231BD93B7DB7DF36F9EB9', |
| 'D8049A43579CFA90B8093A94416CBEFBF93386F15B3F6E190B6E3455FEDFE69A', |
| '605C16178A9BC875DCBFF54D63FE00DF699C03E8A888E9E94DFBAB90B25F39B4'), |
| P256Testvector( |
| 10, |
| '2beedb04b05c6988f6a67500bb813faf2cae0d580c9253b6339e4a3337bb6c08', |
| 'E099BF2A4D557460B5544430BBF6DA11004D127CB5D67F64AB07C94FCDF5274F', |
| 'D9C50DBE70D714EDB5E221F4E020610EEB6270517E688CA64FB0E98C7EF8C1C5', |
| 'F96E40A1B72840854BB62BC13C40CC2795E373D4E715980B261476835A092E0B'), |
| P256Testvector( |
| 11, |
| '77c15dcf44610e41696bab758943eff1409333e4d5a11bbe72c8f6c395e9f848', |
| 'F75A5FE56BDA34F3C1396296626EF012DC07E4825838778A645C8248CFF01658', |
| '33BBDF1B1772D8059DF568B061F3F1122F28A8D819167C97BE448E3DC3FB0C3C', |
| '8388FA79C4BABDCA02A8E8A34F9E43554976E420A4AD273C81B26E4228E9D3A3'), |
| P256Testvector( |
| 12, |
| '42a83b985011d12303db1a800f2610f74aa71cdf19c67d54ce6c9ed951e9093e', |
| '2DB4540D50230756158ABF61D9835712B6486C74312183CCEFCAEF2797B7674D', |
| '62F57F314E3F3495DC4E099012F5E0BA71770F9660A1EADA54104CDFDE77243E', |
| '72877CEA33CCC4715038D4BCBDFE0E43F42A9E2C0C3B017FC2370F4B9ACBDA4A'), |
| P256Testvector( |
| 13, |
| 'ceed35507b5c93ead5989119b9ba342cfe38e6e638ba6eea343a55475de2800b', |
| 'CD94FC9497E8990750309E9A8534FD114B0A6E54DA89C4796101897041D14ECB', |
| 'C3DEF4B5FE04FAEE0A11932229FFF563637BFDEE0E79C6DEEAF449F85401C5C4', |
| 'E4E7408D85FF0E0E9C838003F28CDBD5247CDCE31F32F62494B70E5F1BC36307'), |
| P256Testvector( |
| 14, |
| '43e0e9d95af4dc36483cdd1968d2b7eeb8611fcce77f3a4e7d059ae43e509604', |
| '15B9E467AF4D290C417402E040426FE4CF236BAE72BAA392ED89780DFCCDB471', |
| 'CDF4E9170FB904302B8FD93A820BA8CC7ED4EFD3A6F2D6B05B80B2FF2AEE4E77', |
| 'ED56BCF695B734142C24ECB1FC1BB64D08F175EB243A31F37B3D9BB4407F3B96'), |
| P256Testvector( |
| 15, |
| 'b2f3600df3368ef8a0bb85ab22f41fc0e5f4fdd54be8167a5c3cd4b08db04903', |
| '49C503BA6C4FA605182E186B5E81113F075BC11DCFD51C932FB21E951EEE2FA1', |
| '8AF706FF0922D87B3F0C5E4E31D8B259AEB260A9269643ED520A13BB25DA5924', |
| 'BC5C7055089FC9D6C89F83C1EA1ADA879D9934B2EA28FCF4E4A7E984B28AD2CF'), |
| P256Testvector( |
| 16, |
| '4002534307f8b62a9bf67ff641ddc60fef593b17c3341239e95bdb3e579bfdc8', |
| '19B38DE39FDD2F70F7091631A4F75D1993740BA9429162C2A45312401636B29C', |
| '09AED7232B28E060941741B6828BCDFA2BC49CC844F3773611504F82A390A5AE', |
| '9A4E8E657F6B0E097F47954A63C75D74FCBA71A30D83651E3E5A91AA7CCD8343'), |
| P256Testvector( |
| 17, |
| '4dfa12defc60319021b681b3ff84a10a511958c850939ed45635934ba4979147', |
| '2C91C61F33ADFE9311C942FDBFF6BA47020FEFF416B7BB63CEC13FAF9B099954', |
| '6CAB31B06419E5221FCA014FB84EC870622A1B12BAB5AE43682AA7EA73EA08D0', |
| '3CA1FC7AD858FB1A6ABA232542F3E2A749FFC7203A2374A3F3D3267F1FC97B78'), |
| P256Testvector( |
| 18, |
| '1331f6d874a4ed3bc4a2c6e9c74331d3039796314beee3b7152fcdba5556304e', |
| 'A28A2EDF58025668F724AAF83A50956B7AC1CFBBFF79B08C3BF87DFD2828D767', |
| 'DFA7BFFFD4C766B86ABEAF5C99B6E50CB9CCC9D9D00B7FFC7804B0491B67BC03', |
| '1AAABE7EE6E4A6FA732291202433A237DF1B49BC53866BFBE00DB96A0F58224F'), |
| P256Testvector( |
| 19, |
| 'dd5e9f70ae740073ca0204df60763fb6036c45709bf4a7bb4e671412fad65da3', |
| 'A2EF857A081F9D6EB206A81C4CF78A802BDF598AE380C8886ECD85FDC1ED7644', |
| '563C4C20419F07BC17D0539FADE1855E34839515B892C0F5D26561F97FA04D1A', |
| '430E6A4FBA4449D700D2733E557F66A3BF3D50517C1271B1DDAE1161B7AC798C'), |
| P256Testvector( |
| 20, |
| '5ae026cfc060d55600717e55b8a12e116d1d0df34af831979057607c2d9c2f76', |
| 'CCD8A2D86BC92F2E01BCE4D6922CF7FE1626AED044685E95E2EEBD464505F01F', |
| 'E9DDD583A9635A667777D5B8A8F31B0F79EBA12C75023410B54B8567DDDC0F38', |
| '1CE9E6740529499F98D1F1D71329147A33DF1D05E4765B539B11CF615D6974D3'), |
| P256Testvector( |
| 21, |
| 'b601ac425d5dbf9e1735c5e2d5bdb79ca98b3d5be4a2cfd6f2273f150e064d9d', |
| 'C188FFC8947F7301FB7B53E36746097C2134BF9CC981BA74B4E9C4361F595E4E', |
| 'BF7D2F2056E72421EF393F0C0F2B0E00130E3CAC4ABBCC00286168E85EC55051', |
| '4690E3743C07D643F1BC183636AB2A9CB936A60A802113C49BB1B3F2D0661660'), |
| P256Testvector( |
| 22, |
| 'fefb1dda1845312b5fce6b81b2be205af2f3a274f5a212f66c0d9fc33d7ae535', |
| '317E1020FF53FCCEF18BF47BB7F2DD7707FB7B7A7578E04F35B3BEED222A0EB6', |
| '09420CE5A19D77C6FE1EE587E6A49FBAF8F280E8DF033D75403302E5A27DB2AE', |
| '30C2261BD0004E61FEDA2C16AA5E21FFA8D7E7F7DBF6EC379A43B48E4B36AEB0'), |
| P256Testvector( |
| 23, |
| '334ae0c4693d23935a7e8e043ebbde21e168a7cba3fa507c9be41d7681e049ce', |
| '45FB02B2CEB9D7C79D9C2FA93E9C7967C2FA4DF5789F9640B24264B1E524FCB1', |
| '5C6E8ECF1F7D3023893B7B1CA1E4D178972EE2A230757DDC564FFE37F5C5A321', |
| '2ADAE4A138A239DCD93C243A3803C3E4CF96E37FE14E6A9B717BE9599959B11C'), |
| P256Testvector( |
| 24, |
| '2c4bde40214fcc3bfc47d4cf434b629acbe9157f8fd0282540331de7942cf09d', |
| 'A19EF7BFF98ADA781842FBFC51A47AFF39B5935A1C7D9625C8D323D511C92DE6', |
| 'E9C184DF75C955E02E02E400FFE45F78F339E1AFE6D056FB3245F4700CE606EF', |
| '2E277EC30F5EA07D6CE513149B9479B96E07F4B6913B1B5C11305C1444A1BC0B'), |
| P256Testvector( |
| 25, |
| '85a268f9d7772f990c36b42b0a331adc92b5941de0b862d5d89a347cbf8faab0', |
| '356C5A444C049A52FEE0ADEB7E5D82AE5AA83030BFFF31BBF8CE2096CF161C4B', |
| '57D128DE8B2A57A094D1A001E572173F96E8866AE352BF29CDDAF92FC85B2F92', |
| '1E51373BD2C6044C129C436E742A55BE2A668A85AE08441B6756445DF5493857'), |
| ]; |
| |
| void main() { |
| test('Test ECDH with brainpool keys', () { |
| AsymmetricKeyPair generateKeyPair(int seed) { |
| var rnd = SecureRandom('Fortuna') |
| ..seed(KeyParameter(Uint8List.fromList(List<int>.filled(32, seed)))); |
| |
| var domainParams = ECDomainParameters('brainpoolp256r1'); |
| var ecParams = ECKeyGeneratorParameters(domainParams); |
| var params = |
| ParametersWithRandom<ECKeyGeneratorParameters>(ecParams, rnd); |
| var keygen = KeyGenerator('EC')..init(params); |
| var pcecKeyPair = keygen.generateKeyPair(); |
| return pcecKeyPair; |
| } |
| |
| for (var i = 0; i < 100; i++) { |
| var key1 = generateKeyPair(i); |
| var key2 = generateKeyPair(i + 1); |
| var ecdsa1 = ECDHBasicAgreement()..init(key1.privateKey as ECPrivateKey); |
| var ecdsa2 = ECDHBasicAgreement()..init(key2.privateKey as ECPrivateKey); |
| var ag1 = ecdsa1.calculateAgreement(key2.publicKey as ECPublicKey); |
| var ag2 = ecdsa2.calculateAgreement(key1.publicKey as ECPublicKey); |
| expect(ag1, ag2); |
| } |
| }); |
| |
| test('Test ECDH with jose4j derived testvector for brainpool', () { |
| var z = BigInt.parse( |
| '65138509659007270841390460885129724324131841274570317669830341947633356483036') |
| .toRadixString(16); |
| var bx = BigInt.parse( |
| '9081435728752638263367097265083294633999566778486547389501321800986797192058') |
| .toRadixString(16); |
| var by = BigInt.parse( |
| '42724727959342265773907894856035815102192701310430313271362424512013052339065') |
| .toRadixString(16); |
| var a = BigInt.parse( |
| '11389698291027219705720854063086701177373480468419126898830387062538016871056') |
| .toRadixString(16); |
| |
| var ecdhtestvector = BrainpoolP256r1TestVector(1, a, bx, by, z); |
| var ecdh = ECDHBasicAgreement()..init(ecdhtestvector.privateKey); |
| var ag = ecdh.calculateAgreement(ecdhtestvector.publicKey); |
| expect(ag, ecdhtestvector.Z); |
| }); |
| |
| test('Test ECDHKDF with brainpool', () { |
| var z = BigInt.parse( |
| '65138509659007270841390460885129724324131841274570317669830341947633356483036') |
| .toRadixString(16); |
| var bx = BigInt.parse( |
| '9081435728752638263367097265083294633999566778486547389501321800986797192058') |
| .toRadixString(16); |
| var by = BigInt.parse( |
| '42724727959342265773907894856035815102192701310430313271362424512013052339065') |
| .toRadixString(16); |
| var a = BigInt.parse( |
| '11389698291027219705720854063086701177373480468419126898830387062538016871056') |
| .toRadixString(16); |
| |
| var ecdhtestvector = BrainpoolP256r1TestVector(1, a, bx, by, z); |
| var kdev = KeyDerivator('ECDH'); |
| kdev.init( |
| ECDHKDFParameters(ecdhtestvector.privateKey, ecdhtestvector.publicKey)); |
| var agl = kdev.process(Uint8List(0)); |
| var ag = decodeBigIntWithSign(1, agl); |
| expect(ag, ecdhtestvector.Z); |
| }); |
| |
| test('Test ECDHKDF with brainpool 2', () { |
| var z = BigInt.parse( |
| '52654472886054093008464270686039556607329397624865361587872468137410856915') |
| .toRadixString(16); |
| var bx = BigInt.parse( |
| '11770914954953311947851650675015300970186573673422305697535672144940842288675') |
| .toRadixString(16); |
| var by = BigInt.parse( |
| '28588645609587273162900079046576065116292583182825622980943756235967543473722') |
| .toRadixString(16); |
| var a = BigInt.parse( |
| '11389698291027219705720854063086701177373480468419126898830387062538016871056') |
| .toRadixString(16); |
| |
| var ecdhtestvector = BrainpoolP256r1TestVector(1, a, bx, by, z); |
| var kdev = KeyDerivator('ECDH'); |
| kdev.init( |
| ECDHKDFParameters(ecdhtestvector.privateKey, ecdhtestvector.publicKey)); |
| var agl = kdev.process(Uint8List(0)); |
| var ag = decodeBigIntWithSign(1, agl); |
| expect(ag, ecdhtestvector.Z); |
| }); |
| |
| test('Test ECDH with bouncycastle derived testvector for brainpool', () { |
| var z = BigInt.parse( |
| '62035452719449902544084895701129591677592844515050058000761959332847413670618') |
| .toRadixString(16); |
| var bx = BigInt.parse( |
| '53535355328855043322505278710464138773506437230442680203030305357393812004243') |
| .toRadixString(16); |
| var by = BigInt.parse( |
| '71732587040522161341399014632224799350721466455975116137925664616486205295601') |
| .toRadixString(16); |
| var a = BigInt.parse( |
| '11389698291027219705720854063086701177373480468419126898830387062538016871056') |
| .toRadixString(16); |
| |
| var ecdhtestvector = BrainpoolP256r1TestVector(1, a, bx, by, z); |
| var ecdh = ECDHBasicAgreement()..init(ecdhtestvector.privateKey); |
| var ag = ecdh.calculateAgreement(ecdhtestvector.publicKey); |
| expect(ag, ecdhtestvector.Z); |
| }); |
| |
| test('Test ECDH with brainpool from Test vector of RFC 6932', () { |
| var ecdhtestvector1 = BrainpoolP256r1TestVector( |
| 1, |
| '041EB8B1E2BC681BCE8E39963B2E9FC415B05283313DD1A8BCC055F11AE49699', |
| '8E07E219BA588916C5B06AA30A2F464C2F2ACFC1610A3BE2FB240B635341F0DB', |
| '148EA1D7D1E7E54B9555B6C9AC90629C18B63BEE5D7AA6949EBBF47B24FDE40D', |
| '05E940915549E9F6A4A75693716E37466ABA79B4BF2919877A16DD2CC2E23708'); |
| var ecdhtestvector2 = BrainpoolP256r1TestVector( |
| 2, |
| '06F5240EACDB9837BC96D48274C8AA834B6C87BA9CC3EEDD81F99A16B8D804D3', |
| '78028496B5ECAAB3C8B6C12E45DB1E02C9E4D26B4113BC4F015F60C5CCC0D206', |
| 'A2AE1762A3831C1D20F03F8D1E3C0C39AFE6F09B4D44BBE80CD100987B05F92B', |
| '05E940915549E9F6A4A75693716E37466ABA79B4BF2919877A16DD2CC2E23708'); |
| var ecdh = ECDHBasicAgreement()..init(ecdhtestvector1.privateKey); |
| var ag = ecdh.calculateAgreement(ecdhtestvector1.publicKey); |
| expect(ag, ecdhtestvector1.Z); |
| var ecdh2 = ECDHBasicAgreement()..init(ecdhtestvector2.privateKey); |
| var ag2 = ecdh2.calculateAgreement(ecdhtestvector2.publicKey); |
| expect(ag2, ecdhtestvector2.Z); |
| }); |
| |
| test('Test ECDH with test vectors for P256', () { |
| for (var v in testVectors) { |
| var ecdh = ECDHBasicAgreement()..init(v.privateKey); |
| var ag = ecdh.calculateAgreement(v.publicKey); |
| expect(ag, v.Z); |
| } |
| }); |
| |
| test('Test ECDHKDF with test vectors for P256', () { |
| for (var v in testVectors) { |
| var ecdhparams = ECDHKDFParameters(v.privateKey, v.publicKey); |
| var kdf = KeyDerivator('ECDH')..init(ecdhparams); |
| var ag = decodeBigIntWithSign(1, kdf.process(Uint8List(0))); |
| expect(ag, v.Z); |
| } |
| }); |
| } |