def __init__(self, n=256, m=512, h=60, d=12, w=16, tau=16, k=32): self.n = n self.m = m self.h = h self.d = d self.w = w self.tau = tau self.t = 1 << tau self.k = k self.Hdigest = lambda r, m: BLAKE(512).digest(r + m) self.Fa = lambda a, k: BLAKE(256).digest(k + a) self.Frand = lambda m, k: BLAKE(512).digest(k + m) C = bytes("expand 32-byte to 64-byte state!", 'latin-1') perm = ChaCha().permuted self.Glambda = lambda seed, n: ChaCha(key=seed).keystream(n) self.F = lambda m: perm(m + C)[:32] self.H = lambda m1, m2: perm(xor(perm(m1 + C), m2 + bytes(32)))[:32] self.wots = WOTSplus(n=n, w=w, F=self.F, Gl=self.Glambda) self.horst = HORST(n=n, m=m, k=k, tau=tau, F=self.F, H=self.H, Gt=self.Glambda)
def __init__(self, n=256, m=512, h=60, d=12, w=16, tau=16, k=32): """Initializes SPHINCS (default to SPHINCS-256) !!Everything after this line is unestable!! Currently other parameters than SPHINCS-256 can be buggy n -- length of hash in WOTS / HORST (in bits) m -- length of message hash (in bits) h -- height of the hyper-tree d -- layers of the hyper-tree w -- Winternitz parameter used for WOTS signature tau -- layers in the HORST tree (2^tau is no. of secret-key elements) k -- number of revealed secret-key elements per HORST signature """ self.n = n self.m = m self.h = h self.d = d self.w = w self.tau = tau self.t = 1 << tau self.k = k self.Hdigest = lambda r, m: BLAKE(512).digest(r + m) self.Fa = lambda a, k: BLAKE(256).digest(k + a) self.Frand = lambda m, k: BLAKE(512).digest(k + m) C = bytes("expand 32-byte to 64-byte state!", 'latin-1') perm = ChaCha().permuted self.Glambda = lambda seed, n: ChaCha(key=seed).keystream(n) self.F = lambda m: perm(m + C)[:32] self.H = lambda m1, m2: perm(xor(perm(m1 + C), m2 + bytes(32)))[:32] self.wots = WOTSplus(n=n, w=w, F=self.F, Gl=self.Glambda) self.horst = HORST(n=n, m=m, k=k, tau=tau, F=self.F, H=self.H, Gt=self.Glambda)
def test_BLAKE256_tc2(): result = bytes([ 0xd4, 0x19, 0xba, 0xd3, 0x2d, 0x50, 0x4f, 0xb7, 0xd4, 0x4d, 0x46, 0x0c, 0x42, 0xc5, 0x59, 0x3f, 0xe5, 0x44, 0xfa, 0x4c, 0x13, 0x5d, 0xec, 0x31, 0xe2, 0x1b, 0xd9, 0xab, 0xdc, 0xc2, 0x2d, 0x41 ]) digest = BLAKE(256).digest(bytes(72)) assert result == digest
def test_BLAKE256_tc1(): result = bytes([ 0x0c, 0xe8, 0xd4, 0xef, 0x4d, 0xd7, 0xcd, 0x8d, 0x62, 0xdf, 0xde, 0xd9, 0xd4, 0xed, 0xb0, 0xa7, 0x74, 0xae, 0x6a, 0x41, 0x92, 0x9a, 0x74, 0xda, 0x23, 0x10, 0x9e, 0x8f, 0x11, 0x13, 0x9c, 0x87 ]) digest = BLAKE(256).digest(bytes(1)) assert result == digest
def test_BLAKE512_tc1(): result = bytes([ 0xa8, 0xcf, 0xbb, 0xd7, 0x37, 0x26, 0x06, 0x2d, 0xf0, 0xc6, 0x86, 0x4d, 0xda, 0x65, 0xde, 0xfe, 0x58, 0xef, 0x0c, 0xc5, 0x2a, 0x56, 0x25, 0x09, 0x0f, 0xa1, 0x76, 0x01, 0xe1, 0xee, 0xcd, 0x1b, 0x62, 0x8e, 0x94, 0xf3, 0x96, 0xae, 0x40, 0x2a, 0x00, 0xac, 0xc9, 0xea, 0xb7, 0x7b, 0x4d, 0x4c, 0x2e, 0x85, 0x2a, 0xaa, 0xa2, 0x5a, 0x63, 0x6d, 0x80, 0xaf, 0x3f, 0xc7, 0x91, 0x3e, 0xf5, 0xb8 ]) digest = BLAKE(512).digest(bytes(0)) assert result == digest
def test_BLAKE512_tc3(): result = bytes([ 0x1f, 0x7e, 0x26, 0xf6, 0x3b, 0x6a, 0xd2, 0x5a, 0x08, 0x96, 0xfd, 0x97, 0x8f, 0xd0, 0x50, 0xa1, 0x76, 0x63, 0x91, 0xd2, 0xfd, 0x04, 0x71, 0xa7, 0x7a, 0xfb, 0x97, 0x5e, 0x50, 0x34, 0xb7, 0xad, 0x2d, 0x9c, 0xcf, 0x8d, 0xfb, 0x47, 0xab, 0xbb, 0xe6, 0x56, 0xe1, 0xb8, 0x2f, 0xbc, 0x63, 0x4b, 0xa4, 0x2c, 0xe1, 0x86, 0xe8, 0xdc, 0x5e, 0x1c, 0xe0, 0x9a, 0x88, 0x5d, 0x41, 0xf4, 0x34, 0x51 ]) digest = BLAKE(512).digest("The quick brown fox jumps over the lazy dog") assert result == digest
def test_BLAKE512_tc2(): result = bytes([ 0x97, 0x96, 0x15, 0x87, 0xf6, 0xd9, 0x70, 0xfa, 0xba, 0x6d, 0x24, 0x78, 0x04, 0x5d, 0xe6, 0xd1, 0xfa, 0xbd, 0x09, 0xb6, 0x1a, 0xe5, 0x09, 0x32, 0x05, 0x4d, 0x52, 0xbc, 0x29, 0xd3, 0x1b, 0xe4, 0xff, 0x91, 0x02, 0xb9, 0xf6, 0x9e, 0x2b, 0xbd, 0xb8, 0x3b, 0xe1, 0x3d, 0x4b, 0x9c, 0x06, 0x09, 0x1e, 0x5f, 0xa0, 0xb4, 0x8b, 0xd0, 0x81, 0xb6, 0x34, 0x05, 0x8b, 0xe0, 0xec, 0x49, 0xbe, 0xb3 ]) digest = BLAKE(512).digest(bytes(1)) assert result == digest
in_sk2_bytes = toByteArray(in_sk[32:]) in_masks_bytes = toByteArray(in_masks) exp_root = bytearray.fromhex("0b87b5678179f3c3614ce6181380ee0b434eb7f2aefb9af73e2bcd379b341c95") exp_sigma = chunkbytes(bytearray.fromhex("309ae7ee4abbf3f14f25c3973b62579f176f2cdcb349fa4e32097452bdc2019508974e0c32e99d7c6c6929f099df9052b3fd5c54a8f63e15e06683234fa4014b56e56b21fc94d88ee98cf36aafc81ef9f05201fb755df9b20fb3f7b0f80c258c87dd7bc2927a07617188b3f2d698135763c3dd0667f1291039879fe1c71132b7ec4179296a2619d1b3c01942d45be8f5e792fcf2fb4d16328f3bcdb5f9103c8557e68fcdb234f578956429c39ad0f98092d2f5f885dd9eb8c4e3931474b736ca751d3d247d28506e24de2758cf524b80eb75a6e168426fb38761317fe47c9b302810598c6bc44da3150d8f992d81c0c38458bc613d76b0cda86fdbb7a2b4e89374770064092e719bb735775364231055e62f431361f10b93883e91007c5e43d0b924839590f92feeac6be7852b2f6934f262bee5749574b31194d946f00d9495b27df035c833192a5d0eac8fa80eb8da3f4c95558fcbc155fef2cae7847450bb266775bc3b83cd9064e712697ed6813ca82589d5128d1c8e2786aef4d1a2898e58e9f7ec406829e8fdc35f5b2854a7ee96bd406c9c89b580f941396aa1af1605b87be8040a3832b734f9293ba9d30131d04b0be40931cb3cbaf0be6470d35bd825ab05bb8c67a3751f516e47e9e0354204310a1b1cc0d45f574313de31c0c0993c799aa28dab860045544cfe5f5d860e454b2eb1f927381ba6265582573b1091ebf2f71cd2bd027d41ae6393be3845ad7101a1c2112edac7adeea51518fb68a5465639421503a3a0f26cad6424e3a7dbfb99563fc5d4cd2bc25158b7a85d0265ad28ef1785eb5e128c10105b1c0f64797bd3dcbbb1066eb01bc3fa2be6b629dfefa4947dceaa0f8e0ab1e1afab88c2f9264b1fdf154d098d7aab62b8da8594ef0774b713f49e826b4835bc1256b04628c7af239932255bc800979b9eb7dff05f3b4d1223fbafe4e4c370f86d1155a02add33ce0d56cb99c047076bd535219bbd92f6f9ba8d25a81b65917f5880b2f3a06bd521c20d4fbb38873202914fff360b09626e1f04e737dab3c5a1ac1e2de0656536e418aaca8cf12effbf241c0fa8778ce8c32f5466fd163b38d71c7995b380567fb11bd4e2e6cba287195b1f7351bcf442977a44fdfeaf92b44b240bc28fb2e1863a1f0ad24274f0f251cbbf7cdd10cad89bf7f4305dabfffccb79ab9f7318bb258c70dfb4867063227acfaf921a931081359f7889cf960e26077d8a0210fc4f4b2bab4b48fa081ec00dd71f588a5f477d28c2e186dadabb7fca45b2a8b97e1e4ebbc370527ac6c4ffcc02219d7a04871dbb10c7cc2d054f1c720ed13ad296174d9771139a4dbb5826589de11f27664dd535771a9738bd3549ec5b077756e66d59fb7ec14a358ebee661d6625a718037e790d28442accaff40ce98f45d2c74516888d07c7f46f412bea13919e0cf4936745a9486f3ccc91680d89c8f22f55b6e33d24bf749a78e14ed2188086fd800773f8ab3ae9b938f7c8e24f9e9c2f003ce9f5a4ab2c3ef35eb7b072eb594788ed34dfc1cc08f77344b01c5291c9e114950963b2657878e5da9fbd979cc1646ab4be1c3b5f62260d4f0cc2e85da9563ee12fd6a437e6a0f2f63899e2586023e5f76d4963e4988ae47f6684dca4df688edece725d608241622202169c9875f470dde8cf96142e3b91e21d4ad0f70716ad53bc739f3cbd089c1b5e70a87754f0648a98715afb14e62d142935c61819018be87a510c25fd95de566adc64022da0bd4cee31ece54884f2302c77bfa1a1c7cb464a458f61a76bb2e4178a48e09d85c0f155b32fc4e3df27c19d43ca0737d1c9e03eca3f8d206bdcb39ac64600fb96fcb90d304778d36169127e9f0386e87f56f252519ca643fc5caeae0f27a537947f24e648fcdf76a0273a0041a13df8e3fd0d203dc73845bf0f2ae6ac3ce9e1af589857e7a3b0ce037af829e6358c7c45c4982f14ccf51a534937dffe3b6338bb86172e4761f4523fd4bfe18b94cf9954fcc049ecab08b4d40c25134c0dd4890fc456f8f4fec9f77c106265992a7feaf506fa7d4a78264ea44f90cfd0c333b1f149a27e1ad5ddf0ca77c7f1a2c9c3664afa95b6bc4ee067adf6d7d8083d70e8583eb2cf177fde4c49f03ce4304ac0f8c652ac0f99728a454ce20a3c6517556d88650e6109085c1f09fc271e381adb1ba36fd0f09adfd3268c0e6e14060e2a3cea38bd658dff684c4f613552cfc63374ae253398c40f6f3763935aa019d9ac36e10110a7014330ee12cf2a852f42f6f5ba2090201075ed04bcd41ffc3fcbbe2ab5591104f6d27ca8a28831459f69bbe9c65a626ba6acc42cdd94323a88411c573d9795ff4adfb378774930c9aad3fcccb398dda73d967a767d610cd2318776955807bc86879db091171098c6fa028b0deddcfa4cb63a79e94d1bfb26047c7fcfa526bc04b1fb3c0792af1df3cd32d730d91fbf84e504393013bd44910498988f0acff6593c3cc9814e384132c4e6c59950e316fc9cf6843938e5276eb490c5eb7b4a770dd54461682a6269c1d11575186f8b49657af2c3935c4912540e78eb092aee7bc6b107330f8d258912846badaaca0fb2d4e1684a197b821877bd19378101b3db0b356bdfd5ddebfa61694166f0fea6ce981ca3925a5f7f7664dc60fedd6092aa76cc9b648678ea969d769674c5be84c64b63a9196ec42930b17a9940c0008a24c3fd91d4dd6ee61bbb7191479af1e880bae3abc0385a8794178ceb857d5c65b2e8a1d9253ee5e089fef571f2eb8b8185439c84a155c7c0f80f34442bc5f649c89ee4af4c1341342478dfba3ecee02e2c1ce5cdc8fcbb88164280a8d4b1f09bedb4a1e584a31a958961728726f7a181a3cf79df399ae693c51c47fa270eabf1324f38dafd40935b3fb93331da00265eb367a51824b7894b0ddfe5b858c7eebdd52f390f0db6c2769c333110235dd059889131f371a5661e17ab30faefb82fe0ebe0ee3308d3905e2c3dfe11a28225f8b9972b9010f934bde55c6453523bf5bbf"), 32) subtree_A = int("07c1d4f115363236", 16) target_A = int("103e0ea788a9b191", 16) Glambda = lambda seed, n: ChaCha(key=seed).keystream(n) Gl = lambda seed: Glambda(seed=seed, n=67*32) perm = ChaCha().permuted F = lambda m: perm(m + toByteArray("expand 32-byte to 64-byte state!"))[:32] H = lambda m1, m2: perm(xor(perm(m1 + toByteArray("expand 32-byte to 64-byte state!")), m2 + bytes(32)))[:32] Fa = lambda a, k: BLAKE(256).digest(k + a) Frand = lambda m, k: BLAKE(512).digest(k + m) n = 256 l = 64 + 3 sphincs_bytes = 32 w = 16 h = 60 d = 12 def keygen(in_seed, in_masks): """ W-OTS+ key generation algorithm. """ sk = chunkbytes(Gl(in_seed), sphincs_bytes) masks = chunkbytes(in_masks, sphincs_bytes)