| package org.bouncycastle.pqc.crypto.sphincs; |
| |
| |
| import org.bouncycastle.crypto.Digest; |
| import org.bouncycastle.util.Strings; |
| |
| |
| class HashFunctions |
| { |
| private static final byte[] hashc = Strings.toByteArray("expand 32-byte to 64-byte state!"); |
| |
| private final Digest dig256; |
| private final Digest dig512; |
| private final Permute perm = new Permute(); |
| |
| // for key pair generation where message hash not required |
| HashFunctions(Digest dig256) |
| { |
| this(dig256, null); |
| } |
| |
| HashFunctions(Digest dig256, Digest dig512) |
| { |
| this.dig256 = dig256; |
| this.dig512 = dig512; |
| } |
| |
| int varlen_hash(byte[] out, int outOff, byte[] in, int inLen) |
| { |
| dig256.update(in, 0, inLen); |
| |
| dig256.doFinal(out, outOff); |
| |
| return 0; |
| } |
| |
| Digest getMessageHash() |
| { |
| return dig512; |
| } |
| |
| int hash_2n_n(byte[] out, int outOff, byte[] in, int inOff) |
| { |
| byte[] x = new byte[64]; |
| int i; |
| for (i = 0; i < 32; i++) |
| { |
| x[i] = in[inOff + i]; |
| x[i + 32] = hashc[i]; |
| } |
| perm.chacha_permute(x, x); |
| for (i = 0; i < 32; i++) |
| { |
| x[i] = (byte)(x[i] ^ in[inOff + i + 32]); |
| } |
| perm.chacha_permute(x, x); |
| for (i = 0; i < 32; i++) |
| { |
| out[outOff + i] = x[i]; |
| } |
| |
| return 0; |
| } |
| |
| int hash_2n_n_mask(byte[] out, int outOff, byte[] in, int inOff, byte[] mask, int maskOff) |
| { |
| byte[] buf = new byte[2 * SPHINCS256Config.HASH_BYTES]; |
| int i; |
| for (i = 0; i < 2 * SPHINCS256Config.HASH_BYTES; i++) |
| { |
| buf[i] = (byte)(in[inOff + i] ^ mask[maskOff + i]); |
| } |
| |
| int rv = hash_2n_n(out, outOff, buf, 0); |
| |
| return rv; |
| } |
| |
| int hash_n_n(byte[] out, int outOff, byte[] in, int inOff) |
| { |
| |
| byte[] x = new byte[64]; |
| int i; |
| |
| for (i = 0; i < 32; i++) |
| { |
| x[i] = in[inOff + i]; |
| x[i + 32] = hashc[i]; |
| } |
| perm.chacha_permute(x, x); |
| for (i = 0; i < 32; i++) |
| { |
| out[outOff + i] = x[i]; |
| } |
| |
| return 0; |
| } |
| |
| int hash_n_n_mask(byte[] out, int outOff, byte[] in, int inOff, byte[] mask, int maskOff) |
| { |
| byte[] buf = new byte[SPHINCS256Config.HASH_BYTES]; |
| int i; |
| for (i = 0; i < SPHINCS256Config.HASH_BYTES; i++) |
| { |
| buf[i] = (byte)(in[inOff + i] ^ mask[maskOff + i]); |
| } |
| return hash_n_n(out, outOff, buf, 0); |
| } |
| } |
| |