|
6 | 6 | import org.bouncycastle.crypto.Digest; |
7 | 7 | import org.bouncycastle.math.ec.rfc8032.Ed25519; |
8 | 8 | import org.bouncycastle.util.Arrays; |
| 9 | +import org.bouncycastle.util.Strings; |
9 | 10 | import org.bouncycastle.util.encoders.Hex; |
10 | 11 |
|
11 | 12 | public class Ed25519Test |
@@ -456,6 +457,166 @@ public void testPublicKeyValidationPartial() |
456 | 457 | assertTrue(Ed25519.validatePublicKeyPartial(Hex.decodeStrict("379B071E6F7E2479D5A8588AB708137808D63F689127D4A228E2C1681873C55E"), 0)); |
457 | 458 | } |
458 | 459 |
|
| 460 | + /* |
| 461 | + * Test vectors from the paper "Taming the many EdDSAs" (https://ia.cr/2020/1244). |
| 462 | + */ |
| 463 | + |
| 464 | + public void testTamingNonRepudiation() |
| 465 | + { |
| 466 | + // TODO Algorithm 2 rejects this because A is one of 8 small order points |
| 467 | + |
| 468 | + byte[] msg1 = Strings.toUTF8ByteArray("Send 100 USD to Alice"); |
| 469 | + byte[] msg2 = Strings.toUTF8ByteArray("Send 100000 USD to Alice"); |
| 470 | + byte[] pub = Hex.decodeStrict("ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f"); |
| 471 | + byte[] sig = Hex.decodeStrict("a9d55260f765261eb9b84e106f665e00b867287a761990d7135963ee0a7d59dc" + |
| 472 | + "a5bb704786be79fc476f91d3f3f89b03984d8068dcf1bb7dfc6637b45450ac04"); |
| 473 | + |
| 474 | + assertTrue(Ed25519.verify(sig, 0, pub, 0, msg1, 0, msg1.length)); |
| 475 | + assertTrue(Ed25519.verify(sig, 0, pub, 0, msg2, 0, msg2.length)); |
| 476 | + } |
| 477 | + |
| 478 | + public void testTamingVector_00() |
| 479 | + { |
| 480 | + // TODO Algorithm 2 rejects this because A is one of 8 small order points |
| 481 | + implTamingVector(0, true, |
| 482 | + "8c93255d71dcab10e8f379c26200f3c7bd5f09d9bc3068d3ef4edeb4853022b6", |
| 483 | + "c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa", |
| 484 | + "c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a" + |
| 485 | + "0000000000000000000000000000000000000000000000000000000000000000"); |
| 486 | + } |
| 487 | + |
| 488 | + public void testTamingVector_01() |
| 489 | + { |
| 490 | + // TODO Algorithm 2 rejects this because A is one of 8 small order points |
| 491 | + implTamingVector(1, true, |
| 492 | + "9bd9f44f4dcc75bd531b56b2cd280b0bb38fc1cd6d1230e14861d861de092e79", |
| 493 | + "c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa", |
| 494 | + "f7badec5b8abeaf699583992219b7b223f1df3fbbea919844e3f7c554a43dd43" + |
| 495 | + "a5bb704786be79fc476f91d3f3f89b03984d8068dcf1bb7dfc6637b45450ac04"); |
| 496 | + } |
| 497 | + |
| 498 | + public void testTamingVector_02() |
| 499 | + { |
| 500 | + // NOTE: Algorithm 2 accepts this, although LibSodium rejects R as one of 8 small order points |
| 501 | + implTamingVector(2, true, |
| 502 | + "aebf3f2601a0c8c5d39cc7d8911642f740b78168218da8471772b35f9d35b9ab", |
| 503 | + "f7badec5b8abeaf699583992219b7b223f1df3fbbea919844e3f7c554a43dd43", |
| 504 | + "c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa" + |
| 505 | + "8c4bd45aecaca5b24fb97bc10ac27ac8751a7dfe1baff8b953ec9f5833ca260e"); |
| 506 | + } |
| 507 | + |
| 508 | + public void testTamingVector_03() |
| 509 | + { |
| 510 | + // NOTE: Has mixed-order A and R; a full check could catch this, but is (too) expensive |
| 511 | + implTamingVector(3, true, |
| 512 | + "9bd9f44f4dcc75bd531b56b2cd280b0bb38fc1cd6d1230e14861d861de092e79", |
| 513 | + "cdb267ce40c5cd45306fa5d2f29731459387dbf9eb933b7bd5aed9a765b88d4d", |
| 514 | + "9046a64750444938de19f227bb80485e92b83fdb4b6506c160484c016cc1852f" + |
| 515 | + "87909e14428a7a1d62e9f22f3d3ad7802db02eb2e688b6c52fcd6648a98bd009"); |
| 516 | + } |
| 517 | + |
| 518 | + public void testTamingVector_04() |
| 519 | + { |
| 520 | + // TODO Algorithm 2 accepts this (cofactored verification) |
| 521 | + implTamingVector(4, false, |
| 522 | + "e47d62c63f830dc7a6851a0b1f33ae4bb2f507fb6cffec4011eaccd55b53f56c", |
| 523 | + "cdb267ce40c5cd45306fa5d2f29731459387dbf9eb933b7bd5aed9a765b88d4d", |
| 524 | + "160a1cb0dc9c0258cd0a7d23e94d8fa878bcb1925f2c64246b2dee1796bed512" + |
| 525 | + "5ec6bc982a269b723e0668e540911a9a6a58921d6925e434ab10aa7940551a09"); |
| 526 | + } |
| 527 | + |
| 528 | + public void testTamingVector_05() |
| 529 | + { |
| 530 | + // TODO Algorithm 2 accepts this (cofactored verification) |
| 531 | + implTamingVector(5, false, |
| 532 | + "e47d62c63f830dc7a6851a0b1f33ae4bb2f507fb6cffec4011eaccd55b53f56c", |
| 533 | + "cdb267ce40c5cd45306fa5d2f29731459387dbf9eb933b7bd5aed9a765b88d4d", |
| 534 | + "21122a84e0b5fca4052f5b1235c80a537878b38f3142356b2c2384ebad4668b7" + |
| 535 | + "e40bc836dac0f71076f9abe3a53f9c03c1ceeeddb658d0030494ace586687405"); |
| 536 | + } |
| 537 | + |
| 538 | + public void testTamingVector_06() |
| 539 | + { |
| 540 | + implTamingVector(6, false, |
| 541 | + "85e241a07d148b41e47d62c63f830dc7a6851a0b1f33ae4bb2f507fb6cffec40", |
| 542 | + "442aad9f089ad9e14647b1ef9099a1ff4798d78589e66f28eca69c11f582a623", |
| 543 | + "e96f66be976d82e60150baecff9906684aebb1ef181f67a7189ac78ea23b6c0e" + |
| 544 | + "547f7690a0e2ddcd04d87dbc3490dc19b3b3052f7ff0538cb68afb369ba3a514"); |
| 545 | + } |
| 546 | + |
| 547 | + public void testTamingVector_07() |
| 548 | + { |
| 549 | + implTamingVector(7, false, |
| 550 | + "85e241a07d148b41e47d62c63f830dc7a6851a0b1f33ae4bb2f507fb6cffec40", |
| 551 | + "442aad9f089ad9e14647b1ef9099a1ff4798d78589e66f28eca69c11f582a623", |
| 552 | + "8ce5b96c8f26d0ab6c47958c9e68b937104cd36e13c33566acd2fe8d38aa1942" + |
| 553 | + "7e71f98a4734e74f2f13f06f97c20d58cc3f54b8bd0d272f42b695dd7e89a8c22"); |
| 554 | + } |
| 555 | + |
| 556 | + public void testTamingVector_08() |
| 557 | + { |
| 558 | + implTamingVector(8, false, |
| 559 | + "9bedc267423725d473888631ebf45988bad3db83851ee85c85e241a07d148b41", |
| 560 | + "f7badec5b8abeaf699583992219b7b223f1df3fbbea919844e3f7c554a43dd43", |
| 561 | + "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + |
| 562 | + "03be9678ac102edcd92b0210bb34d7428d12ffc5df5f37e359941266a4e35f0f"); |
| 563 | + } |
| 564 | + |
| 565 | + public void testTamingVector_09() |
| 566 | + { |
| 567 | + implTamingVector(9, false, |
| 568 | + "9bedc267423725d473888631ebf45988bad3db83851ee85c85e241a07d148b41", |
| 569 | + "f7badec5b8abeaf699583992219b7b223f1df3fbbea919844e3f7c554a43dd43", |
| 570 | + "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + |
| 571 | + "ca8c5b64cd208982aa38d4936621a4775aa233aa0505711d8fdcfdaa943d4908"); |
| 572 | + } |
| 573 | + |
| 574 | + public void testTamingVector_10() |
| 575 | + { |
| 576 | + implTamingVector(10, false, |
| 577 | + "e96b7021eb39c1a163b6da4e3093dcd3f21387da4cc4572be588fafae23c155b", |
| 578 | + "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", |
| 579 | + "a9d55260f765261eb9b84e106f665e00b867287a761990d7135963ee0a7d59dc" + |
| 580 | + "a5bb704786be79fc476f91d3f3f89b03984d8068dcf1bb7dfc6637b45450ac04"); |
| 581 | + } |
| 582 | + |
| 583 | + public void testTamingVector_11() |
| 584 | + { |
| 585 | + implTamingVector(11, false, |
| 586 | + "39a591f5321bbe07fd5a23dc2f39d025d74526615746727ceefd6e82ae65c06f", |
| 587 | + "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", |
| 588 | + "a9d55260f765261eb9b84e106f665e00b867287a761990d7135963ee0a7d59dc" + |
| 589 | + "a5bb704786be79fc476f91d3f3f89b03984d8068dcf1bb7dfc6637b45450ac04"); |
| 590 | + } |
| 591 | + |
| 592 | + private static void implTamingVector(int number, boolean expected, String msgHex, String pubHex, String sigHex) |
| 593 | + { |
| 594 | + boolean actual = implTamingVector(msgHex, pubHex, sigHex); |
| 595 | + |
| 596 | + assertEquals("Failed Taming EdDSA Vector #" + number, expected, actual); |
| 597 | + } |
| 598 | + |
| 599 | + private static boolean implTamingVector(String msgHex, String pubHex, String sigHex) |
| 600 | + { |
| 601 | + if (sigHex.length() != Ed25519.SIGNATURE_SIZE * 2) |
| 602 | + { |
| 603 | + return false; |
| 604 | + } |
| 605 | + |
| 606 | + byte[] msg = Hex.decodeStrict(msgHex); |
| 607 | + byte[] pub = Hex.decodeStrict(pubHex); |
| 608 | + byte[] sig = Hex.decodeStrict(sigHex); |
| 609 | + |
| 610 | + try |
| 611 | + { |
| 612 | + return Ed25519.verify(sig, 0, pub, 0, msg, 0, msg.length); |
| 613 | + } |
| 614 | + catch (RuntimeException e) |
| 615 | + { |
| 616 | + return false; |
| 617 | + } |
| 618 | + } |
| 619 | + |
459 | 620 | private static void checkEd25519Vector(String sSK, String sPK, String sM, String sSig, String text) |
460 | 621 | { |
461 | 622 | byte[] sk = Hex.decode(sSK); |
|
0 commit comments