diff options
-rw-r--r-- | crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs | 59 | ||||
-rw-r--r-- | crypto/src/crypto/digests/SkeinEngine.cs | 1584 | ||||
-rw-r--r-- | crypto/src/crypto/engines/ThreefishEngine.cs | 3 | ||||
-rw-r--r-- | crypto/src/crypto/parameters/SkeinParameters.cs | 6 | ||||
-rw-r--r-- | crypto/src/math/ec/ECCurve.cs | 3 | ||||
-rw-r--r-- | crypto/src/math/ec/abc/Tnaf.cs | 2 | ||||
-rw-r--r-- | crypto/src/security/PublicKeyFactory.cs | 2 | ||||
-rw-r--r-- | crypto/src/util/IMemoable.cs | 2 | ||||
-rw-r--r-- | crypto/src/util/MemoableResetException.cs | 40 | ||||
-rw-r--r-- | crypto/test/src/crypto/test/OCBTest.cs | 4 | ||||
-rw-r--r-- | crypto/test/src/test/CertTest.cs | 4 | ||||
-rw-r--r-- | crypto/test/src/test/GOST3410Test.cs | 505 | ||||
-rw-r--r-- | crypto/test/src/test/PKCS10CertRequestTest.cs | 2 |
13 files changed, 1104 insertions, 1112 deletions
diff --git a/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs b/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs index 998e0e06f..b3f55236c 100644 --- a/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs +++ b/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs @@ -15,9 +15,9 @@ namespace Org.BouncyCastle.Asn1.CryptoPro */ public sealed class ECGost3410NamedCurves { - private ECGost3410NamedCurves() - { - } + private ECGost3410NamedCurves() + { + } internal static readonly IDictionary objIds = Platform.CreateHashtable(); internal static readonly IDictionary parameters = Platform.CreateHashtable(); @@ -35,13 +35,12 @@ namespace Org.BouncyCastle.Asn1.CryptoPro ECDomainParameters ecParams = new ECDomainParameters( curve, - curve.CreatePoint( - BigInteger.One, // x - new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612"), // y - false), + curve.CreatePoint( + BigInteger.One, // x + new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612")), // y mod_q); - parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProA] = ecParams; + parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProA] = ecParams; mod_p = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319"); mod_q = new BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323"); @@ -53,10 +52,9 @@ namespace Org.BouncyCastle.Asn1.CryptoPro ecParams = new ECDomainParameters( curve, - curve.CreatePoint( - BigInteger.One, // x - new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612"), // y - false), + curve.CreatePoint( + BigInteger.One, // x + new BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612")), // y mod_q); parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchA] = ecParams; @@ -72,9 +70,8 @@ namespace Org.BouncyCastle.Asn1.CryptoPro ecParams = new ECDomainParameters( curve, curve.CreatePoint( - BigInteger.One, // x - new BigInteger("28792665814854611296992347458380284135028636778229113005756334730996303888124"), // y - false), + BigInteger.One, // x + new BigInteger("28792665814854611296992347458380284135028636778229113005756334730996303888124")), // y mod_q); // q parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProB] = ecParams; @@ -90,9 +87,8 @@ namespace Org.BouncyCastle.Asn1.CryptoPro ecParams = new ECDomainParameters( curve, curve.CreatePoint( - BigInteger.Zero, // x - new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247"), // y - false), + BigInteger.Zero, // x + new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247")), // y mod_q); parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProXchB] = ecParams; @@ -107,12 +103,11 @@ namespace Org.BouncyCastle.Asn1.CryptoPro ecParams = new ECDomainParameters( curve, curve.CreatePoint( - BigInteger.Zero, // x - new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247"), // y - false), + BigInteger.Zero, // x + new BigInteger("29818893917731240733471273240314769927240550812383695689146495261604565990247")), // y mod_q); // q - parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProC] = ecParams; + parameters[CryptoProObjectIdentifiers.GostR3410x2001CryptoProC] = ecParams; objIds["GostR3410-2001-CryptoPro-A"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProA; objIds["GostR3410-2001-CryptoPro-B"] = CryptoProObjectIdentifiers.GostR3410x2001CryptoProB; @@ -139,14 +134,14 @@ namespace Org.BouncyCastle.Asn1.CryptoPro return (ECDomainParameters) parameters[oid]; } - /** - * returns an enumeration containing the name strings for curves - * contained in this structure. - */ - public static IEnumerable Names - { - get { return new EnumerableProxy(objIds.Keys); } - } + /** + * returns an enumeration containing the name strings for curves + * contained in this structure. + */ + public static IEnumerable Names + { + get { return new EnumerableProxy(objIds.Keys); } + } public static ECDomainParameters GetByName( string name) @@ -170,8 +165,8 @@ namespace Org.BouncyCastle.Asn1.CryptoPro return (string) names[oid]; } - public static DerObjectIdentifier GetOid( - string name) + public static DerObjectIdentifier GetOid( + string name) { return (DerObjectIdentifier) objIds[name]; } diff --git a/crypto/src/crypto/digests/SkeinEngine.cs b/crypto/src/crypto/digests/SkeinEngine.cs index 43381e7cf..7e93138ac 100644 --- a/crypto/src/crypto/digests/SkeinEngine.cs +++ b/crypto/src/crypto/digests/SkeinEngine.cs @@ -8,797 +8,797 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Digests { - /// <summary> - /// Implementation of the Skein family of parameterised hash functions in 256, 512 and 1024 bit block - /// sizes, based on the <see cref="Org.BouncyCastle.Crypto.Engines.ThreefishEngine">Threefish</see> tweakable block cipher. - /// </summary> - /// <remarks> - /// This is the 1.3 version of Skein defined in the Skein hash function submission to the NIST SHA-3 - /// competition in October 2010. - /// <p/> - /// Skein was designed by Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting - Mihir - /// Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker. - /// <p/> - /// This implementation is the basis for <see cref="Org.BouncyCastle.Crypto.Digests.SkeinDigest"/> and <see cref="Org.BouncyCastle.Crypto.Macs.SkeinMac"/>, implementing the - /// parameter based configuration system that allows Skein to be adapted to multiple applications. <br> - /// Initialising the engine with <see cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> allows standard and arbitrary parameters to - /// be applied during the Skein hash function. - /// <p/> - /// Implemented: - /// <ul> - /// <li>256, 512 and 1024 bit internal states.</li> - /// <li>Full 96 bit input length.</li> - /// <li>Parameters defined in the Skein specification, and arbitrary other pre and post message - /// parameters.</li> - /// <li>Arbitrary output size in 1 byte intervals.</li> - /// </ul> - /// <p/> - /// Not implemented: - /// <ul> - /// <li>Sub-byte length input (bit padding).</li> - /// <li>Tree hashing.</li> - /// </ul> - /// </remarks> - /// <seealso cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> - public class SkeinEngine - : IMemoable - { - /// <summary> - /// 256 bit block size - Skein-256 - /// </summary> - public const int SKEIN_256 = ThreefishEngine.BLOCKSIZE_256; - /// <summary> - /// 512 bit block size - Skein-512 - /// </summary> - public const int SKEIN_512 = ThreefishEngine.BLOCKSIZE_512; - /// <summary> - /// 1024 bit block size - Skein-1024 - /// </summary> - public const int SKEIN_1024 = ThreefishEngine.BLOCKSIZE_1024; - - // Minimal at present, but more complex when tree hashing is implemented - private class Configuration - { - private byte[] bytes = new byte[32]; - - public Configuration(long outputSizeBits) - { - // 0..3 = ASCII SHA3 - bytes[0] = (byte)'S'; - bytes[1] = (byte)'H'; - bytes[2] = (byte)'A'; - bytes[3] = (byte)'3'; - - // 4..5 = version number in LSB order - bytes[4] = 1; - bytes[5] = 0; - - // 8..15 = output length - ThreefishEngine.WordToBytes((ulong)outputSizeBits, bytes, 8); - } - - public byte[] Bytes - { - get { return bytes; } - } - - } - - public class Parameter - { - private int type; - private byte[] value; - - public Parameter(int type, byte[] value) - { - this.type = type; - this.value = value; - } - - public int Type - { - get { return type; } - } - - public byte[] Value - { - get { return value; } - } - - } - - /** - * The parameter type for the Skein key. - */ - private const int PARAM_TYPE_KEY = 0; - - /** - * The parameter type for the Skein configuration block. - */ - private const int PARAM_TYPE_CONFIG = 4; - - /** - * The parameter type for the message. - */ - private const int PARAM_TYPE_MESSAGE = 48; - - /** - * The parameter type for the output transformation. - */ - private const int PARAM_TYPE_OUTPUT = 63; - - /** - * Precalculated UBI(CFG) states for common state/output combinations without key or other - * pre-message params. - */ - private static readonly IDictionary INITIAL_STATES = Platform.CreateHashtable(); - - static SkeinEngine() - { - // From Appendix C of the Skein 1.3 NIST submission - InitialState(SKEIN_256, 128, new ulong[]{ - 0xe1111906964d7260UL, - 0x883daaa77c8d811cUL, - 0x10080df491960f7aUL, - 0xccf7dde5b45bc1c2UL}); - - InitialState(SKEIN_256, 160, new ulong[]{ - 0x1420231472825e98UL, - 0x2ac4e9a25a77e590UL, - 0xd47a58568838d63eUL, - 0x2dd2e4968586ab7dUL}); - - InitialState(SKEIN_256, 224, new ulong[]{ - 0xc6098a8c9ae5ea0bUL, - 0x876d568608c5191cUL, - 0x99cb88d7d7f53884UL, - 0x384bddb1aeddb5deUL}); - - InitialState(SKEIN_256, 256, new ulong[]{ - 0xfc9da860d048b449UL, - 0x2fca66479fa7d833UL, - 0xb33bc3896656840fUL, - 0x6a54e920fde8da69UL}); - - InitialState(SKEIN_512, 128, new ulong[]{ - 0xa8bc7bf36fbf9f52UL, - 0x1e9872cebd1af0aaUL, - 0x309b1790b32190d3UL, - 0xbcfbb8543f94805cUL, - 0x0da61bcd6e31b11bUL, - 0x1a18ebead46a32e3UL, - 0xa2cc5b18ce84aa82UL, - 0x6982ab289d46982dUL}); - - InitialState(SKEIN_512, 160, new ulong[]{ - 0x28b81a2ae013bd91UL, - 0xc2f11668b5bdf78fUL, - 0x1760d8f3f6a56f12UL, - 0x4fb747588239904fUL, - 0x21ede07f7eaf5056UL, - 0xd908922e63ed70b8UL, - 0xb8ec76ffeccb52faUL, - 0x01a47bb8a3f27a6eUL}); - - InitialState(SKEIN_512, 224, new ulong[]{ - 0xccd0616248677224UL, - 0xcba65cf3a92339efUL, - 0x8ccd69d652ff4b64UL, - 0x398aed7b3ab890b4UL, - 0x0f59d1b1457d2bd0UL, - 0x6776fe6575d4eb3dUL, - 0x99fbc70e997413e9UL, - 0x9e2cfccfe1c41ef7UL}); - - InitialState(SKEIN_512, 384, new ulong[]{ - 0xa3f6c6bf3a75ef5fUL, - 0xb0fef9ccfd84faa4UL, - 0x9d77dd663d770cfeUL, - 0xd798cbf3b468fddaUL, - 0x1bc4a6668a0e4465UL, - 0x7ed7d434e5807407UL, - 0x548fc1acd4ec44d6UL, - 0x266e17546aa18ff8UL}); - - InitialState(SKEIN_512, 512, new ulong[]{ - 0x4903adff749c51ceUL, - 0x0d95de399746df03UL, - 0x8fd1934127c79bceUL, - 0x9a255629ff352cb1UL, - 0x5db62599df6ca7b0UL, - 0xeabe394ca9d5c3f4UL, - 0x991112c71a75b523UL, - 0xae18a40b660fcc33UL}); - } - - private static void InitialState(int blockSize, int outputSize, ulong[] state) - { - INITIAL_STATES.Add(VariantIdentifier(blockSize / 8, outputSize / 8), state); - } - - private static int VariantIdentifier(int blockSizeBytes, int outputSizeBytes) - { - return (outputSizeBytes << 16) | blockSizeBytes; - } - - private class UbiTweak - { - /** - * Point at which position might overflow long, so switch to add with carry logic - */ - private const ulong LOW_RANGE = UInt64.MaxValue - UInt32.MaxValue; - - /** - * Bit 127 = final - */ - private const ulong T1_FINAL = 1UL << 63; - - /** - * Bit 126 = first - */ - private const ulong T1_FIRST = 1UL << 62; - - /** - * UBI uses a 128 bit tweak - */ - private ulong[] tweak = new ulong[2]; - - /** - * Whether 64 bit position exceeded - */ - private bool extendedPosition; - - public UbiTweak() - { - Reset(); - } - - public void Reset(UbiTweak tweak) - { - this.tweak = Arrays.Clone(tweak.tweak, this.tweak); - this.extendedPosition = tweak.extendedPosition; - } - - public void Reset() - { - tweak[0] = 0; - tweak[1] = 0; - extendedPosition = false; - First = true; - } - - public uint Type - { - get - { - return (uint)((tweak[1] >> 56) & 0x3FUL); - } - - set - { - // Bits 120..125 = type - tweak[1] = (tweak[1] & 0xFFFFFFC000000000UL) | ((value & 0x3FUL) << 56); - } - } - - public bool First - { - get - { - return ((tweak[1] & T1_FIRST) != 0); - } - set - { - if (value) - { - tweak[1] |= T1_FIRST; - } - else - { - tweak[1] &= ~T1_FIRST; - } - } - } - - public bool Final - { - get - { - return ((tweak[1] & T1_FINAL) != 0); - } - set - { - if (value) - { - tweak[1] |= T1_FINAL; - } - else - { - tweak[1] &= ~T1_FINAL; - } - } - } - - /** - * Advances the position in the tweak by the specified value. - */ - public void AdvancePosition(int advance) - { - // Bits 0..95 = position - if (extendedPosition) - { - ulong[] parts = new ulong[3]; - parts[0] = tweak[0] & 0xFFFFFFFFUL; - parts[1] = (tweak[0] >> 32) & 0xFFFFFFFFUL; - parts[2] = tweak[1] & 0xFFFFFFFFUL; - - ulong carry = (ulong)advance; - for (int i = 0; i < parts.Length; i++) - { - carry += parts[i]; - parts[i] = carry; - carry >>= 32; - } - tweak[0] = ((parts[1] & 0xFFFFFFFFUL) << 32) | (parts[0] & 0xFFFFFFFFUL); - tweak[1] = (tweak[1] & 0xFFFFFFFF00000000UL) | (parts[2] & 0xFFFFFFFFUL); - } - else - { - ulong position = tweak[0]; - position += (uint)advance; - tweak[0] = position; - if (position > LOW_RANGE) - { - extendedPosition = true; - } - } - } - - public ulong[] GetWords() - { - return tweak; - } - - public override string ToString() - { - return Type + " first: " + First + ", final: " + Final; - } - - } - - /** - * The Unique Block Iteration chaining mode. - */ - // TODO: This might be better as methods... - private class UBI - { - private readonly UbiTweak tweak = new UbiTweak(); - - private readonly SkeinEngine engine; - - /** - * Buffer for the current block of message data - */ - private byte[] currentBlock; - - /** - * Offset into the current message block - */ - private int currentOffset; - - /** - * Buffer for message words for feedback into encrypted block - */ - private ulong[] message; - - public UBI(SkeinEngine engine, int blockSize) - { - this.engine = engine; - currentBlock = new byte[blockSize]; - message = new ulong[currentBlock.Length / 8]; - } - - public void Reset(UBI ubi) - { - currentBlock = Arrays.Clone(ubi.currentBlock, currentBlock); - currentOffset = ubi.currentOffset; - message = Arrays.Clone(ubi.message, this.message); - tweak.Reset(ubi.tweak); - } - - public void Reset(int type) - { - tweak.Reset(); - tweak.Type = (uint)type; - currentOffset = 0; - } - - public void Update(byte[] value, int offset, int len, ulong[] output) - { - /* - * Buffer complete blocks for the underlying Threefish cipher, only flushing when there - * are subsequent bytes (last block must be processed in doFinal() with final=true set). - */ - int copied = 0; - while (len > copied) - { - if (currentOffset == currentBlock.Length) - { - ProcessBlock(output); - tweak.First = false; - currentOffset = 0; - } - - int toCopy = System.Math.Min((len - copied), currentBlock.Length - currentOffset); - Array.Copy(value, offset + copied, currentBlock, currentOffset, toCopy); - copied += toCopy; - currentOffset += toCopy; - tweak.AdvancePosition(toCopy); - } - } - - private void ProcessBlock(ulong[] output) - { - engine.threefish.Init(true, engine.chain, tweak.GetWords()); - for (int i = 0; i < message.Length; i++) - { - message[i] = ThreefishEngine.BytesToWord(currentBlock, i * 8); - } - - engine.threefish.ProcessBlock(message, output); - - for (int i = 0; i < output.Length; i++) - { - output[i] ^= message[i]; - } - } - - public void DoFinal(ulong[] output) - { - // Pad remainder of current block with zeroes - for (int i = currentOffset; i < currentBlock.Length; i++) - { - currentBlock[i] = 0; - } - - tweak.Final = true; - ProcessBlock(output); - } - - } - - /** - * Underlying Threefish tweakable block cipher - */ - private readonly ThreefishEngine threefish; - - /** - * Size of the digest output, in bytes - */ - private readonly int outputSizeBytes; - - /** - * The current chaining/state value - */ - private ulong[] chain; - - /** - * The initial state value - */ - private ulong[] initialState; - - /** - * The (optional) key parameter - */ - private byte[] key; - - /** - * Parameters to apply prior to the message - */ - private Parameter[] preMessageParameters; - - /** - * Parameters to apply after the message, but prior to output - */ - private Parameter[] postMessageParameters; - - /** - * The current UBI operation - */ - private readonly UBI ubi; - - /** - * Buffer for single byte update method - */ - private readonly byte[] singleByte = new byte[1]; - - /// <summary> - /// Constructs a Skein digest with an internal state size and output size. - /// </summary> - /// <param name="stateSizeBits">the internal state size in bits - one of <see cref="SKEIN_256"/> <see cref="SKEIN_512"/> or - /// <see cref="SKEIN_1024"/>.</param> - /// <param name="outputSizeBits">the output/digest size to produce in bits, which must be an integral number of - /// bytes.</param> - public SkeinEngine(int blockSizeBits, int outputSizeBits) - { - if (outputSizeBits % 8 != 0) - { - throw new ArgumentException("Output size must be a multiple of 8 bits. :" + outputSizeBits); - } - // TODO: Prevent digest sizes > block size? - this.outputSizeBytes = outputSizeBits / 8; - - this.threefish = new ThreefishEngine(blockSizeBits); - this.ubi = new UBI(this,threefish.GetBlockSize()); - } - - /// <summary> - /// Creates a SkeinEngine as an exact copy of an existing instance. - /// </summary> - public SkeinEngine(SkeinEngine engine) - : this(engine.BlockSize * 8, engine.OutputSize * 8) - { - CopyIn(engine); - } - - private void CopyIn(SkeinEngine engine) - { - this.ubi.Reset(engine.ubi); - this.chain = Arrays.Clone(engine.chain, this.chain); - this.initialState = Arrays.Clone(engine.initialState, this.initialState); - this.key = Arrays.Clone(engine.key, this.key); - this.preMessageParameters = Clone(engine.preMessageParameters, this.preMessageParameters); - this.postMessageParameters = Clone(engine.postMessageParameters, this.postMessageParameters); - } - - private static Parameter[] Clone(Parameter[] data, Parameter[] existing) - { - if (data == null) - { - return null; - } - if ((existing == null) || (existing.Length != data.Length)) - { - existing = new Parameter[data.Length]; - } - Array.Copy(data, 0, existing, 0, existing.Length); - return existing; - } - - public IMemoable Copy() - { - return new SkeinEngine(this); - } - - public void Reset(IMemoable other) - { - SkeinEngine s = (SkeinEngine)other; - if ((BlockSize != s.BlockSize) || (outputSizeBytes != s.outputSizeBytes)) - { - throw new MemoableResetException("Incompatible parameters in provided SkeinEngine."); - } - CopyIn(s); - } - - public int OutputSize - { - get { return outputSizeBytes; } - } - - public int BlockSize - { - get { return threefish.GetBlockSize (); } - } - - /// <summary> - /// Initialises the Skein engine with the provided parameters. See <see cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> for - /// details on the parameterisation of the Skein hash function. - /// </summary> - /// <param name="parameters">the parameters to apply to this engine, or <code>null</code> to use no parameters.</param> - public void Init(SkeinParameters parameters) - { - this.chain = null; - this.key = null; - this.preMessageParameters = null; - this.postMessageParameters = null; - - if (parameters != null) - { - byte[] key = parameters.GetKey(); - if (key.Length < 16) - { - throw new ArgumentException("Skein key must be at least 128 bits."); - } - InitParams(parameters.GetParameters()); - } - CreateInitialState(); - - // Initialise message block - UbiInit(PARAM_TYPE_MESSAGE); - } - - private void InitParams(IDictionary parameters) - { - IEnumerator keys = parameters.Keys.GetEnumerator(); - IList pre = Platform.CreateArrayList(); - IList post = Platform.CreateArrayList(); - - while (keys.MoveNext()) - { - int type = (int)keys.Current; - byte[] value = (byte[])parameters[type]; - - if (type == PARAM_TYPE_KEY) - { - this.key = value; - } - else if (type < PARAM_TYPE_MESSAGE) - { - pre.Add(new Parameter(type, value)); - } - else - { - post.Add(new Parameter(type, value)); - } - } - preMessageParameters = new Parameter[pre.Count]; - pre.CopyTo(preMessageParameters, 0); - Array.Sort(preMessageParameters); - - postMessageParameters = new Parameter[post.Count]; - post.CopyTo(postMessageParameters, 0); - Array.Sort(postMessageParameters); - } - - /** - * Calculate the initial (pre message block) chaining state. - */ - private void CreateInitialState() - { - ulong[] precalc = (ulong[])INITIAL_STATES[VariantIdentifier(BlockSize, OutputSize)]; - if ((key == null) && (precalc != null)) - { - // Precalculated UBI(CFG) - chain = Arrays.Clone(precalc); - } - else - { - // Blank initial state - chain = new ulong[BlockSize / 8]; - - // Process key block - if (key != null) - { - UbiComplete(SkeinParameters.PARAM_TYPE_KEY, key); - } - - // Process configuration block - UbiComplete(PARAM_TYPE_CONFIG, new Configuration(outputSizeBytes * 8).Bytes); - } - - // Process additional pre-message parameters - if (preMessageParameters != null) - { - for (int i = 0; i < preMessageParameters.Length; i++) - { - Parameter param = preMessageParameters[i]; - UbiComplete(param.Type, param.Value); - } - } - initialState = Arrays.Clone(chain); - } - - /// <summary> - /// Reset the engine to the initial state (with the key and any pre-message parameters , ready to - /// accept message input. - /// </summary> - public void Reset() - { - Array.Copy(initialState, 0, chain, 0, chain.Length); - - UbiInit(PARAM_TYPE_MESSAGE); - } - - private void UbiComplete(int type, byte[] value) - { - UbiInit(type); - this.ubi.Update(value, 0, value.Length, chain); - UbiFinal(); - } - - private void UbiInit(int type) - { - this.ubi.Reset(type); - } - - private void UbiFinal() - { - ubi.DoFinal(chain); - } - - private void CheckInitialised() - { - if (this.ubi == null) - { - throw new ArgumentException("Skein engine is not initialised."); - } - } - - public void Update(byte inByte) - { - singleByte[0] = inByte; - Update(singleByte, 0, 1); - } - - public void Update(byte[] inBytes, int inOff, int len) - { - CheckInitialised(); - ubi.Update(inBytes, inOff, len, chain); - } - - public int DoFinal(byte[] outBytes, int outOff) - { - CheckInitialised(); - if (outBytes.Length < (outOff + outputSizeBytes)) - { - throw new DataLengthException("Output buffer is too short to hold output of " + outputSizeBytes + " bytes"); - } - - // Finalise message block - UbiFinal(); - - // Process additional post-message parameters - if (postMessageParameters != null) - { - for (int i = 0; i < postMessageParameters.Length; i++) - { - Parameter param = postMessageParameters[i]; - UbiComplete(param.Type, param.Value); - } - } - - // Perform the output transform - int blockSize = BlockSize; - int blocksRequired = ((outputSizeBytes + blockSize - 1) / blockSize); - for (int i = 0; i < blocksRequired; i++) - { - int toWrite = System.Math.Min(blockSize, outputSizeBytes - (i * blockSize)); - Output((ulong)i, outBytes, outOff + (i * blockSize), toWrite); - } - - Reset(); - - return outputSizeBytes; - } - - private void Output(ulong outputSequence, byte[] outBytes, int outOff, int outputBytes) - { - byte[] currentBytes = new byte[8]; - ThreefishEngine.WordToBytes(outputSequence, currentBytes, 0); - - // Output is a sequence of UBI invocations all of which use and preserve the pre-output - // state - ulong[] outputWords = new ulong[chain.Length]; - UbiInit(PARAM_TYPE_OUTPUT); - this.ubi.Update(currentBytes, 0, currentBytes.Length, outputWords); - ubi.DoFinal(outputWords); - - int wordsRequired = ((outputBytes + 8 - 1) / 8); - for (int i = 0; i < wordsRequired; i++) - { - int toWrite = System.Math.Min(8, outputBytes - (i * 8)); - if (toWrite == 8) - { - ThreefishEngine.WordToBytes(outputWords[i], outBytes, outOff + (i * 8)); - } - else - { - ThreefishEngine.WordToBytes(outputWords[i], currentBytes, 0); - Array.Copy(currentBytes, 0, outBytes, outOff + (i * 8), toWrite); - } - } - } - - } + /// <summary> + /// Implementation of the Skein family of parameterised hash functions in 256, 512 and 1024 bit block + /// sizes, based on the <see cref="Org.BouncyCastle.Crypto.Engines.ThreefishEngine">Threefish</see> tweakable block cipher. + /// </summary> + /// <remarks> + /// This is the 1.3 version of Skein defined in the Skein hash function submission to the NIST SHA-3 + /// competition in October 2010. + /// <p/> + /// Skein was designed by Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting - Mihir + /// Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker. + /// <p/> + /// This implementation is the basis for <see cref="Org.BouncyCastle.Crypto.Digests.SkeinDigest"/> and <see cref="Org.BouncyCastle.Crypto.Macs.SkeinMac"/>, implementing the + /// parameter based configuration system that allows Skein to be adapted to multiple applications. <br/> + /// Initialising the engine with <see cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> allows standard and arbitrary parameters to + /// be applied during the Skein hash function. + /// <p/> + /// Implemented: + /// <ul> + /// <li>256, 512 and 1024 bit internal states.</li> + /// <li>Full 96 bit input length.</li> + /// <li>Parameters defined in the Skein specification, and arbitrary other pre and post message + /// parameters.</li> + /// <li>Arbitrary output size in 1 byte intervals.</li> + /// </ul> + /// <p/> + /// Not implemented: + /// <ul> + /// <li>Sub-byte length input (bit padding).</li> + /// <li>Tree hashing.</li> + /// </ul> + /// </remarks> + /// <seealso cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> + public class SkeinEngine + : IMemoable + { + /// <summary> + /// 256 bit block size - Skein-256 + /// </summary> + public const int SKEIN_256 = ThreefishEngine.BLOCKSIZE_256; + /// <summary> + /// 512 bit block size - Skein-512 + /// </summary> + public const int SKEIN_512 = ThreefishEngine.BLOCKSIZE_512; + /// <summary> + /// 1024 bit block size - Skein-1024 + /// </summary> + public const int SKEIN_1024 = ThreefishEngine.BLOCKSIZE_1024; + + // Minimal at present, but more complex when tree hashing is implemented + private class Configuration + { + private byte[] bytes = new byte[32]; + + public Configuration(long outputSizeBits) + { + // 0..3 = ASCII SHA3 + bytes[0] = (byte)'S'; + bytes[1] = (byte)'H'; + bytes[2] = (byte)'A'; + bytes[3] = (byte)'3'; + + // 4..5 = version number in LSB order + bytes[4] = 1; + bytes[5] = 0; + + // 8..15 = output length + ThreefishEngine.WordToBytes((ulong)outputSizeBits, bytes, 8); + } + + public byte[] Bytes + { + get { return bytes; } + } + + } + + public class Parameter + { + private int type; + private byte[] value; + + public Parameter(int type, byte[] value) + { + this.type = type; + this.value = value; + } + + public int Type + { + get { return type; } + } + + public byte[] Value + { + get { return value; } + } + + } + + /** + * The parameter type for the Skein key. + */ + private const int PARAM_TYPE_KEY = 0; + + /** + * The parameter type for the Skein configuration block. + */ + private const int PARAM_TYPE_CONFIG = 4; + + /** + * The parameter type for the message. + */ + private const int PARAM_TYPE_MESSAGE = 48; + + /** + * The parameter type for the output transformation. + */ + private const int PARAM_TYPE_OUTPUT = 63; + + /** + * Precalculated UBI(CFG) states for common state/output combinations without key or other + * pre-message params. + */ + private static readonly IDictionary INITIAL_STATES = Platform.CreateHashtable(); + + static SkeinEngine() + { + // From Appendix C of the Skein 1.3 NIST submission + InitialState(SKEIN_256, 128, new ulong[]{ + 0xe1111906964d7260UL, + 0x883daaa77c8d811cUL, + 0x10080df491960f7aUL, + 0xccf7dde5b45bc1c2UL}); + + InitialState(SKEIN_256, 160, new ulong[]{ + 0x1420231472825e98UL, + 0x2ac4e9a25a77e590UL, + 0xd47a58568838d63eUL, + 0x2dd2e4968586ab7dUL}); + + InitialState(SKEIN_256, 224, new ulong[]{ + 0xc6098a8c9ae5ea0bUL, + 0x876d568608c5191cUL, + 0x99cb88d7d7f53884UL, + 0x384bddb1aeddb5deUL}); + + InitialState(SKEIN_256, 256, new ulong[]{ + 0xfc9da860d048b449UL, + 0x2fca66479fa7d833UL, + 0xb33bc3896656840fUL, + 0x6a54e920fde8da69UL}); + + InitialState(SKEIN_512, 128, new ulong[]{ + 0xa8bc7bf36fbf9f52UL, + 0x1e9872cebd1af0aaUL, + 0x309b1790b32190d3UL, + 0xbcfbb8543f94805cUL, + 0x0da61bcd6e31b11bUL, + 0x1a18ebead46a32e3UL, + 0xa2cc5b18ce84aa82UL, + 0x6982ab289d46982dUL}); + + InitialState(SKEIN_512, 160, new ulong[]{ + 0x28b81a2ae013bd91UL, + 0xc2f11668b5bdf78fUL, + 0x1760d8f3f6a56f12UL, + 0x4fb747588239904fUL, + 0x21ede07f7eaf5056UL, + 0xd908922e63ed70b8UL, + 0xb8ec76ffeccb52faUL, + 0x01a47bb8a3f27a6eUL}); + + InitialState(SKEIN_512, 224, new ulong[]{ + 0xccd0616248677224UL, + 0xcba65cf3a92339efUL, + 0x8ccd69d652ff4b64UL, + 0x398aed7b3ab890b4UL, + 0x0f59d1b1457d2bd0UL, + 0x6776fe6575d4eb3dUL, + 0x99fbc70e997413e9UL, + 0x9e2cfccfe1c41ef7UL}); + + InitialState(SKEIN_512, 384, new ulong[]{ + 0xa3f6c6bf3a75ef5fUL, + 0xb0fef9ccfd84faa4UL, + 0x9d77dd663d770cfeUL, + 0xd798cbf3b468fddaUL, + 0x1bc4a6668a0e4465UL, + 0x7ed7d434e5807407UL, + 0x548fc1acd4ec44d6UL, + 0x266e17546aa18ff8UL}); + + InitialState(SKEIN_512, 512, new ulong[]{ + 0x4903adff749c51ceUL, + 0x0d95de399746df03UL, + 0x8fd1934127c79bceUL, + 0x9a255629ff352cb1UL, + 0x5db62599df6ca7b0UL, + 0xeabe394ca9d5c3f4UL, + 0x991112c71a75b523UL, + 0xae18a40b660fcc33UL}); + } + + private static void InitialState(int blockSize, int outputSize, ulong[] state) + { + INITIAL_STATES.Add(VariantIdentifier(blockSize / 8, outputSize / 8), state); + } + + private static int VariantIdentifier(int blockSizeBytes, int outputSizeBytes) + { + return (outputSizeBytes << 16) | blockSizeBytes; + } + + private class UbiTweak + { + /** + * Point at which position might overflow long, so switch to add with carry logic + */ + private const ulong LOW_RANGE = UInt64.MaxValue - UInt32.MaxValue; + + /** + * Bit 127 = final + */ + private const ulong T1_FINAL = 1UL << 63; + + /** + * Bit 126 = first + */ + private const ulong T1_FIRST = 1UL << 62; + + /** + * UBI uses a 128 bit tweak + */ + private ulong[] tweak = new ulong[2]; + + /** + * Whether 64 bit position exceeded + */ + private bool extendedPosition; + + public UbiTweak() + { + Reset(); + } + + public void Reset(UbiTweak tweak) + { + this.tweak = Arrays.Clone(tweak.tweak, this.tweak); + this.extendedPosition = tweak.extendedPosition; + } + + public void Reset() + { + tweak[0] = 0; + tweak[1] = 0; + extendedPosition = false; + First = true; + } + + public uint Type + { + get + { + return (uint)((tweak[1] >> 56) & 0x3FUL); + } + + set + { + // Bits 120..125 = type + tweak[1] = (tweak[1] & 0xFFFFFFC000000000UL) | ((value & 0x3FUL) << 56); + } + } + + public bool First + { + get + { + return ((tweak[1] & T1_FIRST) != 0); + } + set + { + if (value) + { + tweak[1] |= T1_FIRST; + } + else + { + tweak[1] &= ~T1_FIRST; + } + } + } + + public bool Final + { + get + { + return ((tweak[1] & T1_FINAL) != 0); + } + set + { + if (value) + { + tweak[1] |= T1_FINAL; + } + else + { + tweak[1] &= ~T1_FINAL; + } + } + } + + /** + * Advances the position in the tweak by the specified value. + */ + public void AdvancePosition(int advance) + { + // Bits 0..95 = position + if (extendedPosition) + { + ulong[] parts = new ulong[3]; + parts[0] = tweak[0] & 0xFFFFFFFFUL; + parts[1] = (tweak[0] >> 32) & 0xFFFFFFFFUL; + parts[2] = tweak[1] & 0xFFFFFFFFUL; + + ulong carry = (ulong)advance; + for (int i = 0; i < parts.Length; i++) + { + carry += parts[i]; + parts[i] = carry; + carry >>= 32; + } + tweak[0] = ((parts[1] & 0xFFFFFFFFUL) << 32) | (parts[0] & 0xFFFFFFFFUL); + tweak[1] = (tweak[1] & 0xFFFFFFFF00000000UL) | (parts[2] & 0xFFFFFFFFUL); + } + else + { + ulong position = tweak[0]; + position += (uint)advance; + tweak[0] = position; + if (position > LOW_RANGE) + { + extendedPosition = true; + } + } + } + + public ulong[] GetWords() + { + return tweak; + } + + public override string ToString() + { + return Type + " first: " + First + ", final: " + Final; + } + + } + + /** + * The Unique Block Iteration chaining mode. + */ + // TODO: This might be better as methods... + private class UBI + { + private readonly UbiTweak tweak = new UbiTweak(); + + private readonly SkeinEngine engine; + + /** + * Buffer for the current block of message data + */ + private byte[] currentBlock; + + /** + * Offset into the current message block + */ + private int currentOffset; + + /** + * Buffer for message words for feedback into encrypted block + */ + private ulong[] message; + + public UBI(SkeinEngine engine, int blockSize) + { + this.engine = engine; + currentBlock = new byte[blockSize]; + message = new ulong[currentBlock.Length / 8]; + } + + public void Reset(UBI ubi) + { + currentBlock = Arrays.Clone(ubi.currentBlock, currentBlock); + currentOffset = ubi.currentOffset; + message = Arrays.Clone(ubi.message, this.message); + tweak.Reset(ubi.tweak); + } + + public void Reset(int type) + { + tweak.Reset(); + tweak.Type = (uint)type; + currentOffset = 0; + } + + public void Update(byte[] value, int offset, int len, ulong[] output) + { + /* + * Buffer complete blocks for the underlying Threefish cipher, only flushing when there + * are subsequent bytes (last block must be processed in doFinal() with final=true set). + */ + int copied = 0; + while (len > copied) + { + if (currentOffset == currentBlock.Length) + { + ProcessBlock(output); + tweak.First = false; + currentOffset = 0; + } + + int toCopy = System.Math.Min((len - copied), currentBlock.Length - currentOffset); + Array.Copy(value, offset + copied, currentBlock, currentOffset, toCopy); + copied += toCopy; + currentOffset += toCopy; + tweak.AdvancePosition(toCopy); + } + } + + private void ProcessBlock(ulong[] output) + { + engine.threefish.Init(true, engine.chain, tweak.GetWords()); + for (int i = 0; i < message.Length; i++) + { + message[i] = ThreefishEngine.BytesToWord(currentBlock, i * 8); + } + + engine.threefish.ProcessBlock(message, output); + + for (int i = 0; i < output.Length; i++) + { + output[i] ^= message[i]; + } + } + + public void DoFinal(ulong[] output) + { + // Pad remainder of current block with zeroes + for (int i = currentOffset; i < currentBlock.Length; i++) + { + currentBlock[i] = 0; + } + + tweak.Final = true; + ProcessBlock(output); + } + + } + + /** + * Underlying Threefish tweakable block cipher + */ + private readonly ThreefishEngine threefish; + + /** + * Size of the digest output, in bytes + */ + private readonly int outputSizeBytes; + + /** + * The current chaining/state value + */ + private ulong[] chain; + + /** + * The initial state value + */ + private ulong[] initialState; + + /** + * The (optional) key parameter + */ + private byte[] key; + + /** + * Parameters to apply prior to the message + */ + private Parameter[] preMessageParameters; + + /** + * Parameters to apply after the message, but prior to output + */ + private Parameter[] postMessageParameters; + + /** + * The current UBI operation + */ + private readonly UBI ubi; + + /** + * Buffer for single byte update method + */ + private readonly byte[] singleByte = new byte[1]; + + /// <summary> + /// Constructs a Skein digest with an internal state size and output size. + /// </summary> + /// <param name="blockSizeBits">the internal state size in bits - one of <see cref="SKEIN_256"/> <see cref="SKEIN_512"/> or + /// <see cref="SKEIN_1024"/>.</param> + /// <param name="outputSizeBits">the output/digest size to produce in bits, which must be an integral number of + /// bytes.</param> + public SkeinEngine(int blockSizeBits, int outputSizeBits) + { + if (outputSizeBits % 8 != 0) + { + throw new ArgumentException("Output size must be a multiple of 8 bits. :" + outputSizeBits); + } + // TODO: Prevent digest sizes > block size? + this.outputSizeBytes = outputSizeBits / 8; + + this.threefish = new ThreefishEngine(blockSizeBits); + this.ubi = new UBI(this,threefish.GetBlockSize()); + } + + /// <summary> + /// Creates a SkeinEngine as an exact copy of an existing instance. + /// </summary> + public SkeinEngine(SkeinEngine engine) + : this(engine.BlockSize * 8, engine.OutputSize * 8) + { + CopyIn(engine); + } + + private void CopyIn(SkeinEngine engine) + { + this.ubi.Reset(engine.ubi); + this.chain = Arrays.Clone(engine.chain, this.chain); + this.initialState = Arrays.Clone(engine.initialState, this.initialState); + this.key = Arrays.Clone(engine.key, this.key); + this.preMessageParameters = Clone(engine.preMessageParameters, this.preMessageParameters); + this.postMessageParameters = Clone(engine.postMessageParameters, this.postMessageParameters); + } + + private static Parameter[] Clone(Parameter[] data, Parameter[] existing) + { + if (data == null) + { + return null; + } + if ((existing == null) || (existing.Length != data.Length)) + { + existing = new Parameter[data.Length]; + } + Array.Copy(data, 0, existing, 0, existing.Length); + return existing; + } + + public IMemoable Copy() + { + return new SkeinEngine(this); + } + + public void Reset(IMemoable other) + { + SkeinEngine s = (SkeinEngine)other; + if ((BlockSize != s.BlockSize) || (outputSizeBytes != s.outputSizeBytes)) + { + throw new MemoableResetException("Incompatible parameters in provided SkeinEngine."); + } + CopyIn(s); + } + + public int OutputSize + { + get { return outputSizeBytes; } + } + + public int BlockSize + { + get { return threefish.GetBlockSize (); } + } + + /// <summary> + /// Initialises the Skein engine with the provided parameters. See <see cref="Org.BouncyCastle.Crypto.Parameters.SkeinParameters"/> for + /// details on the parameterisation of the Skein hash function. + /// </summary> + /// <param name="parameters">the parameters to apply to this engine, or <code>null</code> to use no parameters.</param> + public void Init(SkeinParameters parameters) + { + this.chain = null; + this.key = null; + this.preMessageParameters = null; + this.postMessageParameters = null; + + if (parameters != null) + { + byte[] key = parameters.GetKey(); + if (key.Length < 16) + { + throw new ArgumentException("Skein key must be at least 128 bits."); + } + InitParams(parameters.GetParameters()); + } + CreateInitialState(); + + // Initialise message block + UbiInit(PARAM_TYPE_MESSAGE); + } + + private void InitParams(IDictionary parameters) + { + IEnumerator keys = parameters.Keys.GetEnumerator(); + IList pre = Platform.CreateArrayList(); + IList post = Platform.CreateArrayList(); + + while (keys.MoveNext()) + { + int type = (int)keys.Current; + byte[] value = (byte[])parameters[type]; + + if (type == PARAM_TYPE_KEY) + { + this.key = value; + } + else if (type < PARAM_TYPE_MESSAGE) + { + pre.Add(new Parameter(type, value)); + } + else + { + post.Add(new Parameter(type, value)); + } + } + preMessageParameters = new Parameter[pre.Count]; + pre.CopyTo(preMessageParameters, 0); + Array.Sort(preMessageParameters); + + postMessageParameters = new Parameter[post.Count]; + post.CopyTo(postMessageParameters, 0); + Array.Sort(postMessageParameters); + } + + /** + * Calculate the initial (pre message block) chaining state. + */ + private void CreateInitialState() + { + ulong[] precalc = (ulong[])INITIAL_STATES[VariantIdentifier(BlockSize, OutputSize)]; + if ((key == null) && (precalc != null)) + { + // Precalculated UBI(CFG) + chain = Arrays.Clone(precalc); + } + else + { + // Blank initial state + chain = new ulong[BlockSize / 8]; + + // Process key block + if (key != null) + { + UbiComplete(SkeinParameters.PARAM_TYPE_KEY, key); + } + + // Process configuration block + UbiComplete(PARAM_TYPE_CONFIG, new Configuration(outputSizeBytes * 8).Bytes); + } + + // Process additional pre-message parameters + if (preMessageParameters != null) + { + for (int i = 0; i < preMessageParameters.Length; i++) + { + Parameter param = preMessageParameters[i]; + UbiComplete(param.Type, param.Value); + } + } + initialState = Arrays.Clone(chain); + } + + /// <summary> + /// Reset the engine to the initial state (with the key and any pre-message parameters , ready to + /// accept message input. + /// </summary> + public void Reset() + { + Array.Copy(initialState, 0, chain, 0, chain.Length); + + UbiInit(PARAM_TYPE_MESSAGE); + } + + private void UbiComplete(int type, byte[] value) + { + UbiInit(type); + this.ubi.Update(value, 0, value.Length, chain); + UbiFinal(); + } + + private void UbiInit(int type) + { + this.ubi.Reset(type); + } + + private void UbiFinal() + { + ubi.DoFinal(chain); + } + + private void CheckInitialised() + { + if (this.ubi == null) + { + throw new ArgumentException("Skein engine is not initialised."); + } + } + + public void Update(byte inByte) + { + singleByte[0] = inByte; + Update(singleByte, 0, 1); + } + + public void Update(byte[] inBytes, int inOff, int len) + { + CheckInitialised(); + ubi.Update(inBytes, inOff, len, chain); + } + + public int DoFinal(byte[] outBytes, int outOff) + { + CheckInitialised(); + if (outBytes.Length < (outOff + outputSizeBytes)) + { + throw new DataLengthException("Output buffer is too short to hold output of " + outputSizeBytes + " bytes"); + } + + // Finalise message block + UbiFinal(); + + // Process additional post-message parameters + if (postMessageParameters != null) + { + for (int i = 0; i < postMessageParameters.Length; i++) + { + Parameter param = postMessageParameters[i]; + UbiComplete(param.Type, param.Value); + } + } + + // Perform the output transform + int blockSize = BlockSize; + int blocksRequired = ((outputSizeBytes + blockSize - 1) / blockSize); + for (int i = 0; i < blocksRequired; i++) + { + int toWrite = System.Math.Min(blockSize, outputSizeBytes - (i * blockSize)); + Output((ulong)i, outBytes, outOff + (i * blockSize), toWrite); + } + + Reset(); + + return outputSizeBytes; + } + + private void Output(ulong outputSequence, byte[] outBytes, int outOff, int outputBytes) + { + byte[] currentBytes = new byte[8]; + ThreefishEngine.WordToBytes(outputSequence, currentBytes, 0); + + // Output is a sequence of UBI invocations all of which use and preserve the pre-output + // state + ulong[] outputWords = new ulong[chain.Length]; + UbiInit(PARAM_TYPE_OUTPUT); + this.ubi.Update(currentBytes, 0, currentBytes.Length, outputWords); + ubi.DoFinal(outputWords); + + int wordsRequired = ((outputBytes + 8 - 1) / 8); + for (int i = 0; i < wordsRequired; i++) + { + int toWrite = System.Math.Min(8, outputBytes - (i * 8)); + if (toWrite == 8) + { + ThreefishEngine.WordToBytes(outputWords[i], outBytes, outOff + (i * 8)); + } + else + { + ThreefishEngine.WordToBytes(outputWords[i], currentBytes, 0); + Array.Copy(currentBytes, 0, outBytes, outOff + (i * 8), toWrite); + } + } + } + + } } diff --git a/crypto/src/crypto/engines/ThreefishEngine.cs b/crypto/src/crypto/engines/ThreefishEngine.cs index 3d4ee8835..954470345 100644 --- a/crypto/src/crypto/engines/ThreefishEngine.cs +++ b/crypto/src/crypto/engines/ThreefishEngine.cs @@ -6,7 +6,6 @@ using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Crypto.Engines { - /// <summary> /// Implementation of the Threefish tweakable large block cipher in 256, 512 and 1024 bit block /// sizes. @@ -19,7 +18,7 @@ namespace Org.BouncyCastle.Crypto.Engines /// Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker. /// <p/> /// This implementation inlines all round functions, unrolls 8 rounds, and uses 1.2k of static tables - /// to speed up key schedule injection. <br> + /// to speed up key schedule injection. <br/> /// 2 x block size state is retained by each cipher instance. /// </remarks> public class ThreefishEngine diff --git a/crypto/src/crypto/parameters/SkeinParameters.cs b/crypto/src/crypto/parameters/SkeinParameters.cs index bbd25e0e0..a4e3e8e2a 100644 --- a/crypto/src/crypto/parameters/SkeinParameters.cs +++ b/crypto/src/crypto/parameters/SkeinParameters.cs @@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Crypto.Parameters /// Parameterised Skein can be used for: /// <ul> /// <li>MAC generation, by providing a <see cref="SkeinParameters.Builder.SetKey(byte[])">key</see>.</li> - /// <li>Randomised hashing, by providing a <see cref="SkeinParameters.Builder.SetNoce(byte[])">nonce</see>.</li> + /// <li>Randomised hashing, by providing a <see cref="SkeinParameters.Builder.SetNonce(byte[])">nonce</see>.</li> /// <li>A hash function for digital signatures, associating a /// <see cref="SkeinParameters.Builder.SetPublicKey(byte[])">public key</see> with the message digest.</li> /// <li>A key derivation function, by providing a @@ -120,7 +120,7 @@ namespace Org.BouncyCastle.Crypto.Parameters } /// <summary> - /// Obtains the value of the <see cref="PARAM_TYPE_KEY_IDENTIFIER key identifier parameter</see>, or + /// Obtains the value of the <see cref="PARAM_TYPE_KEY_IDENTIFIER">key identifier parameter</see>, or /// <code>null</code> if not set. /// </summary> public byte[] GetKeyIdentifier() @@ -129,7 +129,7 @@ namespace Org.BouncyCastle.Crypto.Parameters } /// <summary> - /// Obtains the value of the <see cref="PARAM_TYPE_NONCE nonce parameter</see>, or <code>null</code> if + /// Obtains the value of the <see cref="PARAM_TYPE_NONCE">nonce parameter</see>, or <code>null</code> if /// not set. /// </summary> public byte[] GetNonce() diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs index 0c150848a..82cf1367b 100644 --- a/crypto/src/math/ec/ECCurve.cs +++ b/crypto/src/math/ec/ECCurve.cs @@ -340,7 +340,7 @@ namespace Org.BouncyCastle.Math.EC BigInteger X1 = new BigInteger(1, encoded, 1, expectedLength); BigInteger Y1 = new BigInteger(1, encoded, 1 + expectedLength, expectedLength); - p = CreatePoint(X1, Y1, false); + p = CreatePoint(X1, Y1); break; } @@ -777,6 +777,7 @@ namespace Org.BouncyCastle.Math.EC return new F2mFieldElement(this.m, this.k1, this.k2, this.k3, x); } + [Obsolete("Per-point compression property will be removed")] public override ECPoint CreatePoint(BigInteger x, BigInteger y, bool withCompression) { ECFieldElement X = FromBigInteger(x), Y = FromBigInteger(y); diff --git a/crypto/src/math/ec/abc/Tnaf.cs b/crypto/src/math/ec/abc/Tnaf.cs index 0ba414e68..9f16886f5 100644 --- a/crypto/src/math/ec/abc/Tnaf.cs +++ b/crypto/src/math/ec/abc/Tnaf.cs @@ -534,7 +534,7 @@ namespace Org.BouncyCastle.Math.EC.Abc int m = curve.M; int a = curve.A.ToBigInteger().IntValue; sbyte mu = curve.GetMu(); - int h = curve.H.IntValue; + int h = curve.Cofactor.IntValue; int index = m + 3 - a; BigInteger[] ui = GetLucas(mu, index, false); diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs index b0fc98b03..8c0be4f70 100644 --- a/crypto/src/security/PublicKeyFactory.cs +++ b/crypto/src/security/PublicKeyFactory.cs @@ -187,7 +187,7 @@ namespace Org.BouncyCastle.Security if (ecP == null) return null; - ECPoint q = ecP.Curve.CreatePoint(new BigInteger(1, x), new BigInteger(1, y), false); + ECPoint q = ecP.Curve.CreatePoint(new BigInteger(1, x), new BigInteger(1, y)); return new ECPublicKeyParameters("ECGOST3410", q, gostParams.PublicKeyParamSet); } diff --git a/crypto/src/util/IMemoable.cs b/crypto/src/util/IMemoable.cs index befc10fbf..cc8a2e55b 100644 --- a/crypto/src/util/IMemoable.cs +++ b/crypto/src/util/IMemoable.cs @@ -20,7 +20,7 @@ namespace Org.BouncyCastle.Utilities /// Implementations of this method <em>should</em> try to avoid or minimise memory allocation to perform the reset. /// </remarks> /// <param name="other">an object originally {@link #copy() copied} from an object of the same type as this instance.</param> - /// <exception cref="ClassCastException">if the provided object is not of the correct type.</exception> + /// <exception cref="InvalidCastException">if the provided object is not of the correct type.</exception> /// <exception cref="MemoableResetException">if the <b>other</b> parameter is in some other way invalid.</exception> void Reset(IMemoable other); } diff --git a/crypto/src/util/MemoableResetException.cs b/crypto/src/util/MemoableResetException.cs index d9542dab2..99554f6c2 100644 --- a/crypto/src/util/MemoableResetException.cs +++ b/crypto/src/util/MemoableResetException.cs @@ -2,26 +2,26 @@ using System; namespace Org.BouncyCastle.Utilities { - /** - * Exception to be thrown on a failure to reset an object implementing Memoable. - * <p> - * The exception extends ClassCastException to enable users to have a single handling case, - * only introducing specific handling of this one if required. - * </p> - */ - public class MemoableResetException - : InvalidCastException - { - /** - * Basic Constructor. - * - * @param msg message to be associated with this exception. - */ - public MemoableResetException(string msg) - : base(msg) - { - } - } + /** + * Exception to be thrown on a failure to reset an object implementing Memoable. + * <p> + * The exception extends InvalidCastException to enable users to have a single handling case, + * only introducing specific handling of this one if required. + * </p> + */ + public class MemoableResetException + : InvalidCastException + { + /** + * Basic Constructor. + * + * @param msg message to be associated with this exception. + */ + public MemoableResetException(string msg) + : base(msg) + { + } + } } diff --git a/crypto/test/src/crypto/test/OCBTest.cs b/crypto/test/src/crypto/test/OCBTest.cs index f4c9f3e48..a28e6c3f1 100644 --- a/crypto/test/src/crypto/test/OCBTest.cs +++ b/crypto/test/src/crypto/test/OCBTest.cs @@ -108,7 +108,7 @@ namespace Org.BouncyCastle.Crypto.Tests ocb = new OcbBlockCipher(new DesEngine(), new DesEngine()); Fail("incorrect block size not picked up"); } - catch (ArgumentException e) + catch (ArgumentException) { // expected } @@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Crypto.Tests ocb.Init(false, new KeyParameter(new byte[16])); Fail("illegal argument not picked up"); } - catch (ArgumentException e) + catch (ArgumentException) { // expected } diff --git a/crypto/test/src/test/CertTest.cs b/crypto/test/src/test/CertTest.cs index 2aef010d0..9bb4df7d1 100644 --- a/crypto/test/src/test/CertTest.cs +++ b/crypto/test/src/test/CertTest.cs @@ -1490,7 +1490,7 @@ namespace Org.BouncyCastle.Tests ECPoint q = pubKey.Q.Normalize(); pubKey = new ECPublicKeyParameters( pubKey.AlgorithmName, - q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger(), false), + q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()), pubKey.Parameters); certGen.SetPublicKey(pubKey); @@ -1614,7 +1614,7 @@ namespace Org.BouncyCastle.Tests ECPoint q = pubKey.Q.Normalize(); pubKey = new ECPublicKeyParameters( pubKey.AlgorithmName, - q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger(), false), + q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()), pubKey.Parameters); certGen.SetPublicKey(pubKey); diff --git a/crypto/test/src/test/GOST3410Test.cs b/crypto/test/src/test/GOST3410Test.cs index e8c2c1c76..db232c5a1 100644 --- a/crypto/test/src/test/GOST3410Test.cs +++ b/crypto/test/src/test/GOST3410Test.cs @@ -16,273 +16,270 @@ using Org.BouncyCastle.X509; namespace Org.BouncyCastle.Tests { - [TestFixture] - public class Gost3410Test - : SimpleTest - { - private void ecGOST3410Test() - { - BigInteger r = new BigInteger("29700980915817952874371204983938256990422752107994319651632687982059210933395"); - BigInteger s = new BigInteger("46959264877825372965922731380059061821746083849389763294914877353246631700866"); + [TestFixture] + public class Gost3410Test + : SimpleTest + { + private void ecGOST3410Test() + { + BigInteger r = new BigInteger("29700980915817952874371204983938256990422752107994319651632687982059210933395"); + BigInteger s = new BigInteger("46959264877825372965922731380059061821746083849389763294914877353246631700866"); - byte[] kData = new BigInteger("53854137677348463731403841147996619241504003434302020712960838528893196233395").ToByteArrayUnsigned(); + byte[] kData = new BigInteger("53854137677348463731403841147996619241504003434302020712960838528893196233395").ToByteArrayUnsigned(); - SecureRandom k = FixedSecureRandom.From(kData); + SecureRandom k = FixedSecureRandom.From(kData); - BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p + BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p - ECCurve curve = new FpCurve( - mod_p, // p - new BigInteger("7"), // a - new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b + ECCurve curve = new FpCurve( + mod_p, // p + new BigInteger("7"), // a + new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b - ECDomainParameters spec = new ECDomainParameters( - curve, - curve.CreatePoint( - new BigInteger("2"), - new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"), - false), - new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q + ECDomainParameters spec = new ECDomainParameters( + curve, + curve.CreatePoint( + new BigInteger("2"), + new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280")), + new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q - ECPrivateKeyParameters sKey = new ECPrivateKeyParameters( - "ECGOST3410", - new BigInteger("55441196065363246126355624130324183196576709222340016572108097750006097525544"), // d - spec); + ECPrivateKeyParameters sKey = new ECPrivateKeyParameters( + "ECGOST3410", + new BigInteger("55441196065363246126355624130324183196576709222340016572108097750006097525544"), // d + spec); - ECPublicKeyParameters vKey = new ECPublicKeyParameters( - "ECGOST3410", - curve.CreatePoint( - new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403"), - new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994"), - false), - spec); + ECPublicKeyParameters vKey = new ECPublicKeyParameters( + "ECGOST3410", + curve.CreatePoint( + new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403"), + new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994")), + spec); - ISigner sgr = SignerUtilities.GetSigner("ECGOST3410"); + ISigner sgr = SignerUtilities.GetSigner("ECGOST3410"); - sgr.Init(true, new ParametersWithRandom(sKey, k)); + sgr.Init(true, new ParametersWithRandom(sKey, k)); - byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; + byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' }; - sgr.BlockUpdate(message, 0, message.Length); + sgr.BlockUpdate(message, 0, message.Length); - byte[] sigBytes = sgr.GenerateSignature(); + byte[] sigBytes = sgr.GenerateSignature(); - sgr.Init(false, vKey); + sgr.Init(false, vKey); - sgr.BlockUpdate(message, 0, message.Length); + sgr.BlockUpdate(message, 0, message.Length); - if (!sgr.VerifySignature(sigBytes)) - { - Fail("ECGOST3410 verification failed"); - } + if (!sgr.VerifySignature(sigBytes)) + { + Fail("ECGOST3410 verification failed"); + } - BigInteger[] sig = decode(sigBytes); + BigInteger[] sig = decode(sigBytes); - if (!r.Equals(sig[0])) - { - Fail( - ": r component wrong." + SimpleTest.NewLine - + " expecting: " + r + SimpleTest.NewLine - + " got : " + sig[0]); - } + if (!r.Equals(sig[0])) + { + Fail( + ": r component wrong." + SimpleTest.NewLine + + " expecting: " + r + SimpleTest.NewLine + + " got : " + sig[0]); + } - if (!s.Equals(sig[1])) - { - Fail( - ": s component wrong." + SimpleTest.NewLine - + " expecting: " + s + SimpleTest.NewLine - + " got : " + sig[1]); - } - } + if (!s.Equals(sig[1])) + { + Fail( + ": s component wrong." + SimpleTest.NewLine + + " expecting: " + s + SimpleTest.NewLine + + " got : " + sig[1]); + } + } - private void generationTest() - { - byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; - ISigner s = SignerUtilities.GetSigner("GOST3410"); + private void generationTest() + { + byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; + ISigner s = SignerUtilities.GetSigner("GOST3410"); - IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("GOST3410"); - g.Init( - new Gost3410KeyGenerationParameters( - new SecureRandom(), - CryptoProObjectIdentifiers.GostR3410x94CryptoProA)); + IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("GOST3410"); + g.Init( + new Gost3410KeyGenerationParameters( + new SecureRandom(), + CryptoProObjectIdentifiers.GostR3410x94CryptoProA)); - AsymmetricCipherKeyPair p = g.GenerateKeyPair(); + AsymmetricCipherKeyPair p = g.GenerateKeyPair(); - AsymmetricKeyParameter sKey = p.Private; - AsymmetricKeyParameter vKey = p.Public; + AsymmetricKeyParameter sKey = p.Private; + AsymmetricKeyParameter vKey = p.Public; - s.Init(true, sKey); + s.Init(true, sKey); - s.BlockUpdate(data, 0, data.Length); + s.BlockUpdate(data, 0, data.Length); - byte[] sigBytes = s.GenerateSignature(); + byte[] sigBytes = s.GenerateSignature(); - s = SignerUtilities.GetSigner("GOST3410"); + s = SignerUtilities.GetSigner("GOST3410"); - s.Init(false, vKey); + s.Init(false, vKey); - s.BlockUpdate(data, 0, data.Length); + s.BlockUpdate(data, 0, data.Length); - if (!s.VerifySignature(sigBytes)) - { - Fail("GOST3410 verification failed"); - } + if (!s.VerifySignature(sigBytes)) + { + Fail("GOST3410 verification failed"); + } - // - // default initialisation test - // - s = SignerUtilities.GetSigner("GOST3410"); - g = GeneratorUtilities.GetKeyPairGenerator("GOST3410"); + // + // default initialisation test + // + s = SignerUtilities.GetSigner("GOST3410"); + g = GeneratorUtilities.GetKeyPairGenerator("GOST3410"); - // TODO This is supposed to be a 'default initialisation' test, but don't have a factory - // These values are defaults from JCE provider - g.Init( - new Gost3410KeyGenerationParameters( - new SecureRandom(), - CryptoProObjectIdentifiers.GostR3410x94CryptoProA)); + // TODO This is supposed to be a 'default initialisation' test, but don't have a factory + // These values are defaults from JCE provider + g.Init( + new Gost3410KeyGenerationParameters( + new SecureRandom(), + CryptoProObjectIdentifiers.GostR3410x94CryptoProA)); - p = g.GenerateKeyPair(); + p = g.GenerateKeyPair(); - sKey = p.Private; - vKey = p.Public; + sKey = p.Private; + vKey = p.Public; - s.Init(true, sKey); + s.Init(true, sKey); - s.BlockUpdate(data, 0, data.Length); + s.BlockUpdate(data, 0, data.Length); - sigBytes = s.GenerateSignature(); + sigBytes = s.GenerateSignature(); - s = SignerUtilities.GetSigner("GOST3410"); + s = SignerUtilities.GetSigner("GOST3410"); - s.Init(false, vKey); + s.Init(false, vKey); - s.BlockUpdate(data, 0, data.Length); + s.BlockUpdate(data, 0, data.Length); - if (!s.VerifySignature(sigBytes)) - { - Fail("GOST3410 verification failed"); - } + if (!s.VerifySignature(sigBytes)) + { + Fail("GOST3410 verification failed"); + } - // - // encoded test - // - //KeyFactory f = KeyFactory.getInstance("GOST3410"); - //X509EncodedKeySpec x509s = new X509EncodedKeySpec(vKey.GetEncoded()); - //Gost3410PublicKeyParameters k1 = (Gost3410PublicKeyParameters)f.generatePublic(x509s); - byte[] vKeyEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(vKey).GetDerEncoded(); - Gost3410PublicKeyParameters k1 = (Gost3410PublicKeyParameters) - PublicKeyFactory.CreateKey(vKeyEnc); + // + // encoded test + // + //KeyFactory f = KeyFactory.getInstance("GOST3410"); + //X509EncodedKeySpec x509s = new X509EncodedKeySpec(vKey.GetEncoded()); + //Gost3410PublicKeyParameters k1 = (Gost3410PublicKeyParameters)f.generatePublic(x509s); + byte[] vKeyEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(vKey).GetDerEncoded(); + Gost3410PublicKeyParameters k1 = (Gost3410PublicKeyParameters) + PublicKeyFactory.CreateKey(vKeyEnc); - if (!k1.Y.Equals(((Gost3410PublicKeyParameters)vKey).Y)) - { - Fail("public number not decoded properly"); - } + if (!k1.Y.Equals(((Gost3410PublicKeyParameters)vKey).Y)) + { + Fail("public number not decoded properly"); + } - //PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(sKey.GetEncoded()); - //Gost3410PrivateKeyParameters k2 = (Gost3410PrivateKeyParameters)f.generatePrivate(pkcs8); - byte[] sKeyEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(sKey).GetDerEncoded(); - Gost3410PrivateKeyParameters k2 = (Gost3410PrivateKeyParameters) - PrivateKeyFactory.CreateKey(sKeyEnc); + //PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(sKey.GetEncoded()); + //Gost3410PrivateKeyParameters k2 = (Gost3410PrivateKeyParameters)f.generatePrivate(pkcs8); + byte[] sKeyEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(sKey).GetDerEncoded(); + Gost3410PrivateKeyParameters k2 = (Gost3410PrivateKeyParameters) + PrivateKeyFactory.CreateKey(sKeyEnc); - if (!k2.X.Equals(((Gost3410PrivateKeyParameters)sKey).X)) - { - Fail("private number not decoded properly"); - } + if (!k2.X.Equals(((Gost3410PrivateKeyParameters)sKey).X)) + { + Fail("private number not decoded properly"); + } - // - // ECGOST3410 generation test - // - s = SignerUtilities.GetSigner("ECGOST3410"); - g = GeneratorUtilities.GetKeyPairGenerator("ECGOST3410"); + // + // ECGOST3410 generation test + // + s = SignerUtilities.GetSigner("ECGOST3410"); + g = GeneratorUtilities.GetKeyPairGenerator("ECGOST3410"); - BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p + BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p - ECCurve curve = new FpCurve( - mod_p, // p - new BigInteger("7"), // a - new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b + ECCurve curve = new FpCurve( + mod_p, // p + new BigInteger("7"), // a + new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b - ECDomainParameters ecSpec = new ECDomainParameters( - curve, - curve.CreatePoint( - new BigInteger("2"), - new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"), - false), - new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q + ECDomainParameters ecSpec = new ECDomainParameters( + curve, + curve.CreatePoint( + new BigInteger("2"), + new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280")), + new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q - g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom())); + g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom())); - p = g.GenerateKeyPair(); + p = g.GenerateKeyPair(); - sKey = p.Private; - vKey = p.Public; + sKey = p.Private; + vKey = p.Public; - s.Init(true, sKey); + s.Init(true, sKey); - s.BlockUpdate(data, 0, data.Length); + s.BlockUpdate(data, 0, data.Length); - sigBytes = s.GenerateSignature(); + sigBytes = s.GenerateSignature(); - s = SignerUtilities.GetSigner("ECGOST3410"); + s = SignerUtilities.GetSigner("ECGOST3410"); - s.Init(false, vKey); + s.Init(false, vKey); - s.BlockUpdate(data, 0, data.Length); + s.BlockUpdate(data, 0, data.Length); - if (!s.VerifySignature(sigBytes)) - { - Fail("ECGOST3410 verification failed"); - } - } + if (!s.VerifySignature(sigBytes)) + { + Fail("ECGOST3410 verification failed"); + } + } - private void keyStoreTest( - AsymmetricKeyParameter sKey, - AsymmetricKeyParameter vKey) + private void keyStoreTest( + AsymmetricKeyParameter sKey, + AsymmetricKeyParameter vKey) // throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, UnrecoverableKeyException - { - // - // keystore test - // + { + // + // keystore test + // // KeyStore ks = KeyStore.GetInstance("JKS"); // ks.Load(null, null); - Pkcs12StoreBuilder ksBuilder = new Pkcs12StoreBuilder(); - Pkcs12Store ks = ksBuilder.Build(); - - // - // create the certificate - version 3 - // - X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - - certGen.SetSerialNumber(BigInteger.One); - certGen.SetIssuerDN(new X509Name("CN=Test")); - certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); - certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); - certGen.SetSubjectDN(new X509Name("CN=Test")); - certGen.SetPublicKey(vKey); - certGen.SetSignatureAlgorithm("GOST3411withGOST3410"); - - X509Certificate cert = certGen.Generate(sKey); - X509CertificateEntry certEntry = new X509CertificateEntry(cert); + Pkcs12StoreBuilder ksBuilder = new Pkcs12StoreBuilder(); + Pkcs12Store ks = ksBuilder.Build(); + + // + // create the certificate - version 3 + // + X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); + + certGen.SetSerialNumber(BigInteger.One); + certGen.SetIssuerDN(new X509Name("CN=Test")); + certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50)); + certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50)); + certGen.SetSubjectDN(new X509Name("CN=Test")); + certGen.SetPublicKey(vKey); + certGen.SetSignatureAlgorithm("GOST3411withGOST3410"); + + X509Certificate cert = certGen.Generate(sKey); + X509CertificateEntry certEntry = new X509CertificateEntry(cert); // ks.SetKeyEntry("gost", sKey, "gost".ToCharArray(), new X509Certificate[] { cert }); - ks.SetKeyEntry("gost", new AsymmetricKeyEntry(sKey), new X509CertificateEntry[] { certEntry }); - - MemoryStream bOut = new MemoryStream(); - - ks.Save(bOut, "gost".ToCharArray(), new SecureRandom()); - + ks.SetKeyEntry("gost", new AsymmetricKeyEntry(sKey), new X509CertificateEntry[] { certEntry }); + + MemoryStream bOut = new MemoryStream(); + + ks.Save(bOut, "gost".ToCharArray(), new SecureRandom()); + // ks = KeyStore.getInstance("JKS"); - ks = ksBuilder.Build(); + ks = ksBuilder.Build(); - ks.Load(new MemoryStream(bOut.ToArray(), false), "gost".ToCharArray()); + ks.Load(new MemoryStream(bOut.ToArray(), false), "gost".ToCharArray()); // AsymmetricKeyParameter gKey = (AsymmetricKeyParameter)ks.GetKey("gost", "gost".ToCharArray()); // AsymmetricKeyEntry gKeyEntry = (AsymmetricKeyEntry) - ks.GetKey("gost"); - } - - private void parametersTest() - { + ks.GetKey("gost"); + } + + private void parametersTest() + { // AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("GOST3410"); // a.init(512, random); // AlgorithmParameters params = a.generateParameters(); @@ -303,81 +300,81 @@ namespace Org.BouncyCastle.Tests // GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec( // CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_B.getId()); // g.initialize(gost3410P, new SecureRandom()); - IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("GOST3410"); - g.Init( - new Gost3410KeyGenerationParameters( - new SecureRandom(), - CryptoProObjectIdentifiers.GostR3410x94CryptoProB)); + IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("GOST3410"); + g.Init( + new Gost3410KeyGenerationParameters( + new SecureRandom(), + CryptoProObjectIdentifiers.GostR3410x94CryptoProB)); - AsymmetricCipherKeyPair p = g.GenerateKeyPair(); + AsymmetricCipherKeyPair p = g.GenerateKeyPair(); - AsymmetricKeyParameter sKey = p.Private; - AsymmetricKeyParameter vKey = p.Public; + AsymmetricKeyParameter sKey = p.Private; + AsymmetricKeyParameter vKey = p.Public; - ISigner s = SignerUtilities.GetSigner("GOST3410"); - byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; + ISigner s = SignerUtilities.GetSigner("GOST3410"); + byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; - s.Init(true, sKey); + s.Init(true, sKey); - s.BlockUpdate(data, 0, data.Length); + s.BlockUpdate(data, 0, data.Length); - byte[] sigBytes = s.GenerateSignature(); + byte[] sigBytes = s.GenerateSignature(); - s = SignerUtilities.GetSigner("GOST3410"); + s = SignerUtilities.GetSigner("GOST3410"); - s.Init(false, vKey); + s.Init(false, vKey); - s.BlockUpdate(data, 0, data.Length); + s.BlockUpdate(data, 0, data.Length); - if (!s.VerifySignature(sigBytes)) - { - Fail("GOST3410 verification failed"); - } + if (!s.VerifySignature(sigBytes)) + { + Fail("GOST3410 verification failed"); + } - keyStoreTest(sKey, vKey); - } + keyStoreTest(sKey, vKey); + } - private BigInteger[] decode( - byte[] encoding) - { - byte[] r = new byte[32]; - byte[] s = new byte[32]; + private BigInteger[] decode( + byte[] encoding) + { + byte[] r = new byte[32]; + byte[] s = new byte[32]; - Array.Copy(encoding, 0, s, 0, 32); - Array.Copy(encoding, 32, r, 0, 32); + Array.Copy(encoding, 0, s, 0, 32); + Array.Copy(encoding, 32, r, 0, 32); - BigInteger[] sig = new BigInteger[2]; + BigInteger[] sig = new BigInteger[2]; - sig[0] = new BigInteger(1, r); - sig[1] = new BigInteger(1, s); + sig[0] = new BigInteger(1, r); + sig[1] = new BigInteger(1, s); - return sig; - } + return sig; + } - public override string Name - { - get { return "GOST3410/ECGOST3410"; } - } + public override string Name + { + get { return "GOST3410/ECGOST3410"; } + } - public override void PerformTest() - { - ecGOST3410Test(); - generationTest(); - parametersTest(); - } + public override void PerformTest() + { + ecGOST3410Test(); + generationTest(); + parametersTest(); + } - public static void Main( - string[] args) - { - RunTest(new Gost3410Test()); - } + public static void Main( + string[] args) + { + RunTest(new Gost3410Test()); + } - [Test] - public void TestFunction() - { - string resultText = Perform().ToString(); + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); - Assert.AreEqual(Name + ": Okay", resultText); - } - } + Assert.AreEqual(Name + ": Okay", resultText); + } + } } diff --git a/crypto/test/src/test/PKCS10CertRequestTest.cs b/crypto/test/src/test/PKCS10CertRequestTest.cs index 8af43b2e4..819439cd8 100644 --- a/crypto/test/src/test/PKCS10CertRequestTest.cs +++ b/crypto/test/src/test/PKCS10CertRequestTest.cs @@ -177,7 +177,7 @@ namespace Org.BouncyCastle.Tests ECPoint q = pubKey.Q.Normalize(); pubKey = new ECPublicKeyParameters( pubKey.AlgorithmName, - q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger(), false), + q.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()), pubKey.Parameters); req = new Pkcs10CertificationRequest( |