diff options
author | Sergio Giro <sgiro@google.com> | 2016-02-01 14:37:23 +0000 |
---|---|---|
committer | Sergio Giro <sgiro@google.com> | 2016-02-01 15:16:12 +0000 |
commit | 397d32894b89b506dc318e0f83446187c9b76ebe (patch) | |
tree | 8229ff72c8cbb06f49dce3a8382930919fa6fc2b /bcprov/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java | |
parent | 9b30eb05e5be69d51881a0d1b31e503e97acd784 (diff) | |
parent | 6d876f3f0ae553704a1dcf7e89003fcf14717037 (diff) | |
download | android_external_bouncycastle-397d32894b89b506dc318e0f83446187c9b76ebe.tar.gz android_external_bouncycastle-397d32894b89b506dc318e0f83446187c9b76ebe.tar.bz2 android_external_bouncycastle-397d32894b89b506dc318e0f83446187c9b76ebe.zip |
Merge remote-tracking branch 'aosp/upstream-master' into merge-152-from-upstream
As to set a common ancestor for future merges from aosp/upstream-master
(when updating to new versions of bouncycastle).
We'll override all the changes of this commit with patch
https://android-review.googlesource.com/#/c/199872
Change-Id: I53a7f797b520a6e119878dbae53246cdcc585ddf
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java')
-rw-r--r-- | bcprov/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java new file mode 100644 index 0000000..0fb7375 --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java @@ -0,0 +1,152 @@ +package org.bouncycastle.crypto.signers; + +import java.math.BigInteger; +import java.security.SecureRandom; + +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.BigIntegers; + +/** + * A deterministic K calculator based on the algorithm in section 3.2 of RFC 6979. + */ +public class HMacDSAKCalculator + implements DSAKCalculator +{ + private static final BigInteger ZERO = BigInteger.valueOf(0); + + private final HMac hMac; + private final byte[] K; + private final byte[] V; + + private BigInteger n; + + /** + * Base constructor. + * + * @param digest digest to build the HMAC on. + */ + public HMacDSAKCalculator(Digest digest) + { + this.hMac = new HMac(digest); + this.V = new byte[hMac.getMacSize()]; + this.K = new byte[hMac.getMacSize()]; + } + + public boolean isDeterministic() + { + return true; + } + + public void init(BigInteger n, SecureRandom random) + { + throw new IllegalStateException("Operation not supported"); + } + + public void init(BigInteger n, BigInteger d, byte[] message) + { + this.n = n; + + Arrays.fill(V, (byte)0x01); + Arrays.fill(K, (byte)0); + + byte[] x = new byte[(n.bitLength() + 7) / 8]; + byte[] dVal = BigIntegers.asUnsignedByteArray(d); + + System.arraycopy(dVal, 0, x, x.length - dVal.length, dVal.length); + + byte[] m = new byte[(n.bitLength() + 7) / 8]; + + BigInteger mInt = bitsToInt(message); + + if (mInt.compareTo(n) >= 0) + { + mInt = mInt.subtract(n); + } + + byte[] mVal = BigIntegers.asUnsignedByteArray(mInt); + + System.arraycopy(mVal, 0, m, m.length - mVal.length, mVal.length); + + hMac.init(new KeyParameter(K)); + + hMac.update(V, 0, V.length); + hMac.update((byte)0x00); + hMac.update(x, 0, x.length); + hMac.update(m, 0, m.length); + + hMac.doFinal(K, 0); + + hMac.init(new KeyParameter(K)); + + hMac.update(V, 0, V.length); + + hMac.doFinal(V, 0); + + hMac.update(V, 0, V.length); + hMac.update((byte)0x01); + hMac.update(x, 0, x.length); + hMac.update(m, 0, m.length); + + hMac.doFinal(K, 0); + + hMac.init(new KeyParameter(K)); + + hMac.update(V, 0, V.length); + + hMac.doFinal(V, 0); + } + + public BigInteger nextK() + { + byte[] t = new byte[((n.bitLength() + 7) / 8)]; + + for (;;) + { + int tOff = 0; + + while (tOff < t.length) + { + hMac.update(V, 0, V.length); + + hMac.doFinal(V, 0); + + int len = Math.min(t.length - tOff, V.length); + System.arraycopy(V, 0, t, tOff, len); + tOff += len; + } + + BigInteger k = bitsToInt(t); + + if (k.compareTo(ZERO) > 0 && k.compareTo(n) < 0) + { + return k; + } + + hMac.update(V, 0, V.length); + hMac.update((byte)0x00); + + hMac.doFinal(K, 0); + + hMac.init(new KeyParameter(K)); + + hMac.update(V, 0, V.length); + + hMac.doFinal(V, 0); + } + } + + private BigInteger bitsToInt(byte[] t) + { + BigInteger v = new BigInteger(1, t); + + if (t.length * 8 > n.bitLength()) + { + v = v.shiftRight(t.length * 8 - n.bitLength()); + } + + return v; + } +} |