From cc6ae8aadad5c7f26acd6e6633362f2d88525732 Mon Sep 17 00:00:00 2001 From: Vladimir Babin Date: Fri, 9 Feb 2024 10:44:38 +0300 Subject: [PATCH 1/2] Update Secp256k1 --- Package.swift | 7 +- Sources/VIZ/Block.swift | 4 +- Sources/VIZ/Extensions/Data+Random.swift | 19 + .../VIZ/Extensions/Pointers+Convenience.swift | 17 + Sources/VIZ/PrivateKey.swift | 6 +- Sources/VIZ/PublicKey.swift | 4 +- Sources/VIZ/Secp256k1.swift | 220 +++- Sources/VIZ/Signature.swift | 2 +- Sources/secp256k1/include/secp256k1.h | 767 ----------- Sources/secp256k1/src/ecdsa.h | 21 - Sources/secp256k1/src/ecdsa_impl.h | 313 ----- Sources/secp256k1/src/eckey.h | 25 - Sources/secp256k1/src/eckey_impl.h | 100 -- Sources/secp256k1/src/ecmult.h | 47 - Sources/secp256k1/src/ecmult_const.h | 17 - Sources/secp256k1/src/ecmult_const_impl.h | 257 ---- Sources/secp256k1/src/ecmult_gen.h | 43 - Sources/secp256k1/src/ecmult_gen_impl.h | 210 --- Sources/secp256k1/src/ecmult_impl.h | 1027 --------------- Sources/secp256k1/src/field.h | 121 -- Sources/secp256k1/src/field_10x26.h | 48 - Sources/secp256k1/src/field_10x26_impl.h | 1161 ----------------- Sources/secp256k1/src/field_impl.h | 306 ----- Sources/secp256k1/src/group.h | 147 --- Sources/secp256k1/src/group_impl.h | 706 ---------- Sources/secp256k1/src/hash.h | 41 - Sources/secp256k1/src/hash_impl.h | 282 ---- .../secp256k1/src/modules/ecdh/main_impl.h | 54 - .../src/modules/recovery/main_impl.h | 193 --- Sources/secp256k1/src/num.h | 12 - Sources/secp256k1/src/num_impl.h | 12 - Sources/secp256k1/src/scalar.h | 95 -- Sources/secp256k1/src/scalar_8x32.h | 19 - Sources/secp256k1/src/scalar_8x32_impl.h | 721 ---------- Sources/secp256k1/src/scalar_impl.h | 320 ----- Sources/secp256k1/src/scratch.h | 39 - Sources/secp256k1/src/scratch_impl.h | 86 -- Sources/secp256k1/src/secp256k1.c | 592 --------- Sources/secp256k1/src/util.h | 121 -- Tests/UnitTests/Secp256k1.swift | 8 +- 40 files changed, 226 insertions(+), 7964 deletions(-) create mode 100644 Sources/VIZ/Extensions/Data+Random.swift create mode 100644 Sources/VIZ/Extensions/Pointers+Convenience.swift delete mode 100644 Sources/secp256k1/include/secp256k1.h delete mode 100644 Sources/secp256k1/src/ecdsa.h delete mode 100644 Sources/secp256k1/src/ecdsa_impl.h delete mode 100644 Sources/secp256k1/src/eckey.h delete mode 100644 Sources/secp256k1/src/eckey_impl.h delete mode 100644 Sources/secp256k1/src/ecmult.h delete mode 100644 Sources/secp256k1/src/ecmult_const.h delete mode 100644 Sources/secp256k1/src/ecmult_const_impl.h delete mode 100644 Sources/secp256k1/src/ecmult_gen.h delete mode 100644 Sources/secp256k1/src/ecmult_gen_impl.h delete mode 100644 Sources/secp256k1/src/ecmult_impl.h delete mode 100644 Sources/secp256k1/src/field.h delete mode 100644 Sources/secp256k1/src/field_10x26.h delete mode 100644 Sources/secp256k1/src/field_10x26_impl.h delete mode 100644 Sources/secp256k1/src/field_impl.h delete mode 100644 Sources/secp256k1/src/group.h delete mode 100644 Sources/secp256k1/src/group_impl.h delete mode 100644 Sources/secp256k1/src/hash.h delete mode 100644 Sources/secp256k1/src/hash_impl.h delete mode 100644 Sources/secp256k1/src/modules/ecdh/main_impl.h delete mode 100755 Sources/secp256k1/src/modules/recovery/main_impl.h delete mode 100644 Sources/secp256k1/src/num.h delete mode 100644 Sources/secp256k1/src/num_impl.h delete mode 100644 Sources/secp256k1/src/scalar.h delete mode 100644 Sources/secp256k1/src/scalar_8x32.h delete mode 100644 Sources/secp256k1/src/scalar_8x32_impl.h delete mode 100644 Sources/secp256k1/src/scalar_impl.h delete mode 100644 Sources/secp256k1/src/scratch.h delete mode 100644 Sources/secp256k1/src/scratch_impl.h delete mode 100644 Sources/secp256k1/src/secp256k1.c delete mode 100644 Sources/secp256k1/src/util.h diff --git a/Package.swift b/Package.swift index 096d291..cfea13c 100644 --- a/Package.swift +++ b/Package.swift @@ -17,19 +17,16 @@ let package = Package( url: "https://github.com/lukaskubanek/OrderedDictionary.git", from: "4.0.0" ), + .package(name: "secp256k1gm", url: "https://github.com/greymass/secp256k1.git", .branch("master")), ], targets: [ .target( name: "Crypto", dependencies: [] ), - .target( - name: "secp256k1", - dependencies: [] - ), .target( name: "VIZ", - dependencies: ["Crypto", "AnyCodable", "OrderedDictionary", "secp256k1"] + dependencies: ["Crypto", "AnyCodable", "OrderedDictionary", "secp256k1gm"] ), .testTarget( name: "UnitTests", diff --git a/Sources/VIZ/Block.swift b/Sources/VIZ/Block.swift index 84baa6a..945747a 100644 --- a/Sources/VIZ/Block.swift +++ b/Sources/VIZ/Block.swift @@ -9,12 +9,12 @@ public struct BlockId: Codable, Equatable { public var hash: Data /// The block number. public var num: UInt32 { - return UInt32(bigEndian: self.hash.withUnsafeBytes { $0.pointee }) + return UInt32(bigEndian: self.hash.withUnsafeBytes { $0.load(as: UInt32.self) }) } /// The block prefix. public var prefix: UInt32 { - return UInt32(littleEndian: self.hash.suffix(from: 4).withUnsafeBytes { $0.pointee }) + return UInt32(littleEndian: self.hash.suffix(from: 4).withUnsafeBytes { $0.load(as: UInt32.self) }) } public init(from decoder: Decoder) throws { diff --git a/Sources/VIZ/Extensions/Data+Random.swift b/Sources/VIZ/Extensions/Data+Random.swift new file mode 100644 index 0000000..93f9469 --- /dev/null +++ b/Sources/VIZ/Extensions/Data+Random.swift @@ -0,0 +1,19 @@ +/// Random byte generation extension for the Data type. +/// - Author: Johan Nordberg + +import Foundation + +public extension Data { + static func random(_ count: Int, using generator: inout T) -> Data { + var data = Data(capacity: count) + for _ in 0.. Data { + var rng = SystemRandomNumberGenerator() + return Self.random(count, using: &rng) + } +} diff --git a/Sources/VIZ/Extensions/Pointers+Convenience.swift b/Sources/VIZ/Extensions/Pointers+Convenience.swift new file mode 100644 index 0000000..8996925 --- /dev/null +++ b/Sources/VIZ/Extensions/Pointers+Convenience.swift @@ -0,0 +1,17 @@ +import Foundation + +internal extension UnsafeRawBufferPointer { + /// Returns a C compatible buffer pointer. + /// - Attention:Unsafe to use unless count > 0 + var bufPtr: UnsafePointer { + self.baseAddress!.assumingMemoryBound(to: UInt8.self) + } +} + +internal extension UnsafeMutableRawBufferPointer { + /// Returns a C compatible mutable buffer pointer. + /// - Attention:Unsafe to use unless count > 0 + var bufPtr: UnsafeMutablePointer { + self.baseAddress!.assumingMemoryBound(to: UInt8.self) + } +} diff --git a/Sources/VIZ/PrivateKey.swift b/Sources/VIZ/PrivateKey.swift index fd4293f..aae147d 100644 --- a/Sources/VIZ/PrivateKey.swift +++ b/Sources/VIZ/PrivateKey.swift @@ -17,7 +17,7 @@ public struct PrivateKey: Equatable { return nil } let secret = data.suffix(from: 1) - guard Secp256k1Context.shared.verify(secretKey: secret) else { + guard Secp256k1.shared.verify(secretKey: secret) else { return nil } self.secret = secret @@ -52,7 +52,7 @@ public struct PrivateKey: Equatable { } else { ndata = Random.bytes(count: 32) } - result = try Secp256k1Context.shared.sign(message: message, secretKey: self.secret, ndata: ndata) + result = try Secp256k1.shared.sign(message: message, secretKey: self.secret, ndata: ndata) } while (!isCanonicalSignature(result.0)) return Signature(signature: result.0, recoveryId: UInt8(result.1)) } @@ -60,7 +60,7 @@ public struct PrivateKey: Equatable { /// Derive the public key for this private key. /// - Parameter prefix: Address prefix to use when creating key, defaults to main net (STM). public func createPublic(prefix: PublicKey.AddressPrefix = .mainNet) -> PublicKey { - let result = try! Secp256k1Context.shared.createPublic(fromSecret: self.secret) + let result = try! Secp256k1.shared.createPublic(fromSecret: self.secret) return PublicKey(key: result, prefix: prefix)! } diff --git a/Sources/VIZ/PublicKey.swift b/Sources/VIZ/PublicKey.swift index 80c6b23..ccab63a 100644 --- a/Sources/VIZ/PublicKey.swift +++ b/Sources/VIZ/PublicKey.swift @@ -54,8 +54,8 @@ public struct PublicKey: Equatable { } extension PublicKey: Hashable { - public var hashValue: Int { - return self.key.withUnsafeBytes { $0.pointee } + self.prefix.hashValue + public func hash(into hasher: inout Hasher) { + hasher.combine(key.withUnsafeBytes { $0.load(as: Int.self) } + self.prefix.hashValue) } } diff --git a/Sources/VIZ/Secp256k1.swift b/Sources/VIZ/Secp256k1.swift index 552d249..946ca51 100644 --- a/Sources/VIZ/Secp256k1.swift +++ b/Sources/VIZ/Secp256k1.swift @@ -1,10 +1,12 @@ -/// Swift libsecp256k1 bindings -/// - Author: Johan Nordberg +/// Swift wrapper for libsecp256k1. +/// - Author: Johan Nordberg +import Crypto import Foundation -import secp256k1 +import secp256k1gm -internal class Secp256k1Context { +/// Class representing a libsecp256k1 context. +internal class Secp256k1 { struct Flags: OptionSet { let rawValue: Int32 static let none = Flags(rawValue: SECP256K1_CONTEXT_NONE) @@ -15,39 +17,84 @@ internal class Secp256k1Context { enum Error: Swift.Error { /// The secret key is invalid or the nonce generation failed. case signingFailed - /// Unable to parse compact signature + /// Unable to parse compact signature. case invalidSignature - /// Unable to recover public key from signature + /// Unable to recover public key from signature. case recoveryFailed - /// Invalid private key + /// Invalid private key. case invalidSecretKey + /// Thrown if unable to parse public key data. + case invalidPublicKey + /// Thrown if randomization seed isn't 32-bytes. + case invalidRandomSeed + /// Thrown if randomization unexpectedly fails. + case randomizationFailed + /// Thrown if message isn't 32-bytes. + case invalidMessage } - /// Shared context. - static let shared = Secp256k1Context(flags: [.sign, .verify]) + /// The shared secp256k1 context. + /// + /// Shared context is thread-safe and should be used in most cases since creating a new + /// context is 100 times more expensive than a signing or verifying operation. + static let shared: Secp256k1 = { + let ctx = Secp256k1(flags: [.sign, .verify]) + try? ctx.randomize(using: Data.random(32)) + return ctx + }() private let ctx: OpaquePointer /// Create a new context. /// - Parameter flags: Flags used to initialize the context. - init(flags: Secp256k1Context.Flags = .none) { + init(flags: Flags = .none) { self.ctx = secp256k1_context_create(UInt32(flags.rawValue)) - let seed = Random.bytes(count: 32) - _ = seed.withUnsafeBytes { - secp256k1_context_randomize(self.ctx, $0) - } } deinit { secp256k1_context_destroy(self.ctx) } + /// Updates the context randomization to protect against side-channel leakage. + /// - Parameter seed: 32-byte random seed. + /// - Throws: If seed is invalid or randomization fails. + /// + /// While secp256k1 code is written to be constant-time no matter what secret + /// values are, it's possible that a future compiler may output code which isn't, + /// and also that the CPU may not emit the same radio frequencies or draw the + /// same amount power for all values. + /// + /// This function provides a seed which is combined into the blinding value: that + /// blinding value is added before each multiplication (and removed afterwards) so + /// that it does not affect function results, but shields against attacks which + /// rely on any input-dependent behaviour. + /// + /// This function has currently an effect only on contexts initialized for signing + /// because randomization is currently used only for signing. However, this is not + /// guaranteed and may change in the future. It is safe to call this function on + /// contexts not initialized for signing. + /// + /// - Attention: Not thread-safe. + func randomize(using seed: Data) throws { + try seed.withUnsafeBytes { + guard $0.count == 32 else { + throw Error.invalidRandomSeed + } + guard secp256k1_context_randomize(self.ctx, $0.bufPtr) == 1 else { + throw Error.randomizationFailed + } + } + } + /// Verify a private key. /// - Parameter secretKey: 32-byte secret key to verify. /// - Returns: true if valid; false otherwise. func verify(secretKey key: Data) -> Bool { return key.withUnsafeBytes { - secp256k1_ec_seckey_verify(self.ctx, $0) == 1 + guard $0.count == 32 else { + return false + } + return secp256k1_ec_seckey_verify(self.ctx, $0.bufPtr) == 1 } } @@ -55,24 +102,26 @@ internal class Secp256k1Context { /// - Parameter publicKey: Opaque data structure that holds a parsed and valid public key. /// - Parameter compressed: Whether to compress the key when serializing. /// - Returns: 33-byte or 65-byte public key. - func serialize(publicKey pubkey: UnsafePointer, compressed: Bool = true) -> Data { + private func serialize(publicKey pubkey: UnsafePointer, compressed: Bool = true) -> Data { var size: Int = compressed ? 33 : 65 let flags = compressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED var rv = Data(count: size) - _ = rv.withUnsafeMutableBytes { - secp256k1_ec_pubkey_serialize(self.ctx, $0, &size, pubkey, UInt32(flags)) + rv.withUnsafeMutableBytes { + secp256k1_ec_pubkey_serialize(self.ctx, $0.bufPtr, &size, pubkey, UInt32(flags)) + return } return rv } - /// Serialize a signature. + /// Serialize an ECDSA signature in compact format (64 bytes + recovery id). /// - Parameter recoverableSignature: Opaque data structured that holds a parsed ECDSA signature, supporting pubkey recovery. /// - Returns: 64-byte signature and recovery id. - func serialize(recoverableSignature sig: UnsafePointer) -> (Data, Int32) { + private func serialize(recoverableSignature sig: UnsafePointer) -> (Data, Int32) { var signature = Data(count: 64) var recid: Int32 = -1 - _ = signature.withUnsafeMutableBytes { - secp256k1_ecdsa_recoverable_signature_serialize_compact(self.ctx, $0, &recid, sig) + signature.withUnsafeMutableBytes { + secp256k1_ecdsa_recoverable_signature_serialize_compact(self.ctx, $0.bufPtr, &recid, sig) + return } return (signature, recid) } @@ -83,11 +132,13 @@ internal class Secp256k1Context { func createPublic(fromSecret key: Data) throws -> Data { let pubkey = UnsafeMutablePointer.allocate(capacity: 1) defer { pubkey.deallocate() } - let success = key.withUnsafeBytes { - secp256k1_ec_pubkey_create(self.ctx, pubkey, $0) == 1 - } - guard success else { - throw Error.invalidSecretKey + try key.withUnsafeBytes { + guard $0.count == 32 else { + throw Error.invalidSecretKey + } + guard secp256k1_ec_pubkey_create(self.ctx, pubkey, $0.bufPtr) == 1 else { + throw Error.invalidSecretKey + } } return self.serialize(publicKey: pubkey) } @@ -100,20 +151,29 @@ internal class Secp256k1Context { func sign(message: Data, secretKey key: Data, ndata: Data? = nil) throws -> (Data, Int32) { let sig = UnsafeMutablePointer.allocate(capacity: 1) defer { sig.deallocate() } - let success = message.withUnsafeBytes { (msgPtr: UnsafePointer) -> Bool in - return key.withUnsafeBytes { (keyPtr: UnsafePointer) -> Bool in + try message.withUnsafeBytes { + guard $0.count == 32 else { + throw Error.invalidMessage + } + let msgPtr = $0.bufPtr + try key.withUnsafeBytes { + guard $0.count == 32 else { + throw Error.invalidSecretKey + } + let keyPtr = $0.bufPtr + let res: Int32 if let ndata = ndata { - return ndata.withUnsafeBytes { (ndataPtr: UnsafePointer) -> Bool in - secp256k1_ecdsa_sign_recoverable(self.ctx, sig, msgPtr, keyPtr, nil, ndataPtr) == 1 + res = ndata.withUnsafeBytes { + secp256k1_ecdsa_sign_recoverable(self.ctx, sig, msgPtr, keyPtr, nil, $0.baseAddress) } } else { - return secp256k1_ecdsa_sign_recoverable(self.ctx, sig, msgPtr, keyPtr, nil, nil) == 1 + res = secp256k1_ecdsa_sign_recoverable(self.ctx, sig, msgPtr, keyPtr, nil, nil) + } + guard res == 1 else { + throw Error.signingFailed } } } - guard success else { - throw Error.signingFailed - } return self.serialize(recoverableSignature: sig) } @@ -125,20 +185,92 @@ internal class Secp256k1Context { func recover(message: Data, signature: Data, recoveryId recid: Int32) throws -> Data { let sig = UnsafeMutablePointer.allocate(capacity: 1) defer { sig.deallocate() } - let parseSuccess = signature.withUnsafeBytes { - secp256k1_ecdsa_recoverable_signature_parse_compact(self.ctx, sig, $0, recid) == 1 + try signature.withUnsafeBytes { + guard $0.count == 64 else { + throw Error.invalidSignature + } + guard secp256k1_ecdsa_recoverable_signature_parse_compact(self.ctx, sig, $0.bufPtr, recid) == 1 else { + throw Error.invalidSignature + } + } + let pubkey = UnsafeMutablePointer.allocate(capacity: 1) + defer { pubkey.deallocate() } + try message.withUnsafeBytes { + guard $0.count == 32 else { + throw Error.invalidMessage + } + guard secp256k1_ecdsa_recover(self.ctx, pubkey, sig, $0.bufPtr) == 1 else { + throw Error.recoveryFailed + } + } + return self.serialize(publicKey: pubkey) + } + + /// Verify signature using given message and public key. + /// - Parameter signature: 64-byte signature. + /// - Parameter message: 32-byte message to verify. + /// - Parameter publicKey: 33- or 65-byte public key to verify against. + /// - Returns: `true` verification is successful, `false` otherwise. + func verify(signature: Data, message: Data, publicKey: Data) -> Bool { + let sig = UnsafeMutablePointer.allocate(capacity: 1) + defer { sig.deallocate() } + guard signature.withUnsafeBytes({ + guard $0.count == 64 else { + return false + } + return secp256k1_ecdsa_signature_parse_compact(self.ctx, sig, $0.bufPtr) == 1 + }) else { + return false } - guard parseSuccess else { - throw Error.invalidSignature + let pubkey = UnsafeMutablePointer.allocate(capacity: 1) + defer { pubkey.deallocate() } + guard publicKey.withUnsafeBytes({ + guard !$0.isEmpty else { + return false + } + return secp256k1_ec_pubkey_parse(self.ctx, pubkey, $0.bufPtr, $0.count) == 1 + }) else { + return false } + return message.withUnsafeBytes { msg32 -> Bool in + guard msg32.count == 32 else { + return false + } + return secp256k1_ecdsa_verify(self.ctx, sig, msg32.bufPtr, pubkey) == 1 + } + } + + /// Compute an EC Diffie-Hellman (ECDH) secret using SHA512. + /// - Parameter publicKey: 33- or 65-byte public key. + /// - Parameter secretKey: 32-byte secret key. + /// - Returns: 64-byte shared secret. + func sharedSecret(publicKey: Data, secretKey: Data) throws -> Data { let pubkey = UnsafeMutablePointer.allocate(capacity: 1) defer { pubkey.deallocate() } - let recoverSuccess = message.withUnsafeBytes { - secp256k1_ecdsa_recover(self.ctx, pubkey, sig, $0) == 1 + try publicKey.withUnsafeBytes { + guard !$0.isEmpty else { + throw Error.invalidPublicKey + } + guard secp256k1_ec_pubkey_parse(ctx, pubkey, $0.bufPtr, $0.count) == 1 else { + throw Error.invalidPublicKey + } } - guard recoverSuccess else { - throw Error.recoveryFailed + let output = UnsafeMutablePointer.allocate(capacity: 64) + try secretKey.withUnsafeBytes { + guard !$0.isEmpty else { + throw Error.invalidSecretKey + } + guard secp256k1_ecdh(self.ctx, output, pubkey, $0.bufPtr, sha512_hash, nil) == 1 else { + throw Error.invalidSecretKey + } } - return self.serialize(publicKey: pubkey) + return Data(bytesNoCopy: output, count: 64, deallocator: .free) } } + +/// EOSIO-style EDCH hash function +/// https://github.com/EOSIO/eosjs-ecc/blob/97c87d9a3ea338636ceb351116b5cc858710bd39/src/key_private.js#L81 +private func sha512_hash(output: UnsafeMutablePointer?, x: UnsafePointer?, y _: UnsafePointer?, data _: UnsafeMutableRawPointer?) -> Int32 { + sha512_Raw(x, 32, output) + return 1 +} diff --git a/Sources/VIZ/Signature.swift b/Sources/VIZ/Signature.swift index d938d06..e0fde2b 100644 --- a/Sources/VIZ/Signature.swift +++ b/Sources/VIZ/Signature.swift @@ -33,7 +33,7 @@ public struct Signature: Equatable, LosslessStringConvertible { /// - Parameter prefix: The address prefix to use for the resulting public key, optional. /// - Returns: The public key used to create the signature or nil if the recovery was unsucessful. public func recover(message: Data, prefix: PublicKey.AddressPrefix = .mainNet) -> PublicKey? { - guard let key = try? Secp256k1Context.shared.recover(message: message, signature: self.signature, recoveryId: Int32(self.recoveryId)) else { + guard let key = try? Secp256k1.shared.recover(message: message, signature: self.signature, recoveryId: Int32(self.recoveryId)) else { return nil } return PublicKey(key: key, prefix: prefix)! diff --git a/Sources/secp256k1/include/secp256k1.h b/Sources/secp256k1/include/secp256k1.h deleted file mode 100644 index ad6b159..0000000 --- a/Sources/secp256k1/include/secp256k1.h +++ /dev/null @@ -1,767 +0,0 @@ -#ifndef SECP256K1_H -#define SECP256K1_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* These rules specify the order of arguments in API calls: - * - * 1. Context pointers go first, followed by output arguments, combined - * output/input arguments, and finally input-only arguments. - * 2. Array lengths always immediately the follow the argument whose length - * they describe, even if this violates rule 1. - * 3. Within the OUT/OUTIN/IN groups, pointers to data that is typically generated - * later go first. This means: signatures, public nonces, private nonces, - * messages, public keys, secret keys, tweaks. - * 4. Arguments that are not data pointers go last, from more complex to less - * complex: function pointers, algorithm names, messages, void pointers, - * counts, flags, booleans. - * 5. Opaque data pointers follow the function pointer they are to be passed to. - */ - -/** Opaque data structure that holds context information (precomputed tables etc.). - * - * The purpose of context structures is to cache large precomputed data tables - * that are expensive to construct, and also to maintain the randomization data - * for blinding. - * - * Do not create a new context object for each operation, as construction is - * far slower than all other API calls (~100 times slower than an ECDSA - * verification). - * - * A constructed context can safely be used from multiple threads - * simultaneously, but API call that take a non-const pointer to a context - * need exclusive access to it. In particular this is the case for - * secp256k1_context_destroy and secp256k1_context_randomize. - * - * Regarding randomization, either do it once at creation time (in which case - * you do not need any locking for the other calls), or use a read-write lock. - */ -typedef struct secp256k1_context_struct secp256k1_context; - -/** Opaque data structure that holds rewriteable "scratch space" - * - * The purpose of this structure is to replace dynamic memory allocations, - * because we target architectures where this may not be available. It is - * essentially a resizable (within specified parameters) block of bytes, - * which is initially created either by memory allocation or TODO as a pointer - * into some fixed rewritable space. - * - * Unlike the context object, this cannot safely be shared between threads - * without additional synchronization logic. - */ -typedef struct secp256k1_scratch_space_struct secp256k1_scratch_space; - -/** Opaque data structure that holds a parsed and valid public key. - * - * The exact representation of data inside is implementation defined and not - * guaranteed to be portable between different platforms or versions. It is - * however guaranteed to be 64 bytes in size, and can be safely copied/moved. - * If you need to convert to a format suitable for storage, transmission, or - * comparison, use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. - */ -typedef struct { - unsigned char data[64]; -} secp256k1_pubkey; - -/** Opaque data structured that holds a parsed ECDSA signature. - * - * The exact representation of data inside is implementation defined and not - * guaranteed to be portable between different platforms or versions. It is - * however guaranteed to be 64 bytes in size, and can be safely copied/moved. - * If you need to convert to a format suitable for storage, transmission, or - * comparison, use the secp256k1_ecdsa_signature_serialize_* and - * secp256k1_ecdsa_signature_parse_* functions. - */ -typedef struct { - unsigned char data[64]; -} secp256k1_ecdsa_signature; - -/** A pointer to a function to deterministically generate a nonce. - * - * Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail. - * Out: nonce32: pointer to a 32-byte array to be filled by the function. - * In: msg32: the 32-byte message hash being verified (will not be NULL) - * key32: pointer to a 32-byte secret key (will not be NULL) - * algo16: pointer to a 16-byte array describing the signature - * algorithm (will be NULL for ECDSA for compatibility). - * data: Arbitrary data pointer that is passed through. - * attempt: how many iterations we have tried to find a nonce. - * This will almost always be 0, but different attempt values - * are required to result in a different nonce. - * - * Except for test cases, this function should compute some cryptographic hash of - * the message, the algorithm, the key and the attempt. - */ -typedef int (*secp256k1_nonce_function)( - unsigned char *nonce32, - const unsigned char *msg32, - const unsigned char *key32, - const unsigned char *algo16, - void *data, - unsigned int attempt -); - -# if !defined(SECP256K1_GNUC_PREREQ) -# if defined(__GNUC__)&&defined(__GNUC_MINOR__) -# define SECP256K1_GNUC_PREREQ(_maj,_min) \ - ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) -# else -# define SECP256K1_GNUC_PREREQ(_maj,_min) 0 -# endif -# endif - -# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) -# if SECP256K1_GNUC_PREREQ(2,7) -# define SECP256K1_INLINE __inline__ -# elif (defined(_MSC_VER)) -# define SECP256K1_INLINE __inline -# else -# define SECP256K1_INLINE -# endif -# else -# define SECP256K1_INLINE inline -# endif - -#ifndef SECP256K1_API -# if defined(_WIN32) -# ifdef SECP256K1_BUILD -# define SECP256K1_API __declspec(dllexport) -# else -# define SECP256K1_API -# endif -# elif defined(__GNUC__) && defined(SECP256K1_BUILD) -# define SECP256K1_API __attribute__ ((visibility ("default"))) -# else -# define SECP256K1_API -# endif -#endif - -/**Warning attributes - * NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out - * some paranoid null checks. */ -# if defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4) -# define SECP256K1_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) -# else -# define SECP256K1_WARN_UNUSED_RESULT -# endif -# if !defined(SECP256K1_BUILD) && defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4) -# define SECP256K1_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) -# else -# define SECP256K1_ARG_NONNULL(_x) -# endif - -/** All flags' lower 8 bits indicate what they're for. Do not use directly. */ -#define SECP256K1_FLAGS_TYPE_MASK ((1 << 8) - 1) -#define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0) -#define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1) -/** The higher bits contain the actual data. Do not use directly. */ -#define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY (1 << 8) -#define SECP256K1_FLAGS_BIT_CONTEXT_SIGN (1 << 9) -#define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8) - -/** Flags to pass to secp256k1_context_create. */ -#define SECP256K1_CONTEXT_VERIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) -#define SECP256K1_CONTEXT_SIGN (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN) -#define SECP256K1_CONTEXT_NONE (SECP256K1_FLAGS_TYPE_CONTEXT) - -/** Flag to pass to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export. */ -#define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION) -#define SECP256K1_EC_UNCOMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION) - -/** Prefix byte used to tag various encoded curvepoints for specific purposes */ -#define SECP256K1_TAG_PUBKEY_EVEN 0x02 -#define SECP256K1_TAG_PUBKEY_ODD 0x03 -#define SECP256K1_TAG_PUBKEY_UNCOMPRESSED 0x04 -#define SECP256K1_TAG_PUBKEY_HYBRID_EVEN 0x06 -#define SECP256K1_TAG_PUBKEY_HYBRID_ODD 0x07 - -/** Create a secp256k1 context object. - * - * Returns: a newly created context object. - * In: flags: which parts of the context to initialize. - * - * See also secp256k1_context_randomize. - */ -SECP256K1_API secp256k1_context* secp256k1_context_create( - unsigned int flags -) SECP256K1_WARN_UNUSED_RESULT; - -/** Copies a secp256k1 context object. - * - * Returns: a newly created context object. - * Args: ctx: an existing context to copy (cannot be NULL) - */ -SECP256K1_API secp256k1_context* secp256k1_context_clone( - const secp256k1_context* ctx -) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; - -/** Destroy a secp256k1 context object. - * - * The context pointer may not be used afterwards. - * Args: ctx: an existing context to destroy (cannot be NULL) - */ -SECP256K1_API void secp256k1_context_destroy( - secp256k1_context* ctx -); - -/** Set a callback function to be called when an illegal argument is passed to - * an API call. It will only trigger for violations that are mentioned - * explicitly in the header. - * - * The philosophy is that these shouldn't be dealt with through a - * specific return value, as calling code should not have branches to deal with - * the case that this code itself is broken. - * - * On the other hand, during debug stage, one would want to be informed about - * such mistakes, and the default (crashing) may be inadvisable. - * When this callback is triggered, the API function called is guaranteed not - * to cause a crash, though its return value and output arguments are - * undefined. - * - * Args: ctx: an existing context object (cannot be NULL) - * In: fun: a pointer to a function to call when an illegal argument is - * passed to the API, taking a message and an opaque pointer - * (NULL restores a default handler that calls abort). - * data: the opaque pointer to pass to fun above. - */ -SECP256K1_API void secp256k1_context_set_illegal_callback( - secp256k1_context* ctx, - void (*fun)(const char* message, void* data), - const void* data -) SECP256K1_ARG_NONNULL(1); - -/** Set a callback function to be called when an internal consistency check - * fails. The default is crashing. - * - * This can only trigger in case of a hardware failure, miscompilation, - * memory corruption, serious bug in the library, or other error would can - * otherwise result in undefined behaviour. It will not trigger due to mere - * incorrect usage of the API (see secp256k1_context_set_illegal_callback - * for that). After this callback returns, anything may happen, including - * crashing. - * - * Args: ctx: an existing context object (cannot be NULL) - * In: fun: a pointer to a function to call when an internal error occurs, - * taking a message and an opaque pointer (NULL restores a default - * handler that calls abort). - * data: the opaque pointer to pass to fun above. - */ -SECP256K1_API void secp256k1_context_set_error_callback( - secp256k1_context* ctx, - void (*fun)(const char* message, void* data), - const void* data -) SECP256K1_ARG_NONNULL(1); - -/** Create a secp256k1 scratch space object. - * - * Returns: a newly created scratch space. - * Args: ctx: an existing context object (cannot be NULL) - * In: max_size: maximum amount of memory to allocate - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space* secp256k1_scratch_space_create( - const secp256k1_context* ctx, - size_t max_size -) SECP256K1_ARG_NONNULL(1); - -/** Destroy a secp256k1 scratch space. - * - * The pointer may not be used afterwards. - * Args: scratch: space to destroy - */ -SECP256K1_API void secp256k1_scratch_space_destroy( - secp256k1_scratch_space* scratch -); - -/** Parse a variable-length public key into the pubkey object. - * - * Returns: 1 if the public key was fully valid. - * 0 if the public key could not be parsed or is invalid. - * Args: ctx: a secp256k1 context object. - * Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a - * parsed version of input. If not, its value is undefined. - * In: input: pointer to a serialized public key - * inputlen: length of the array pointed to by input - * - * This function supports parsing compressed (33 bytes, header byte 0x02 or - * 0x03), uncompressed (65 bytes, header byte 0x04), or hybrid (65 bytes, header - * byte 0x06 or 0x07) format public keys. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse( - const secp256k1_context* ctx, - secp256k1_pubkey* pubkey, - const unsigned char *input, - size_t inputlen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Serialize a pubkey object into a serialized byte sequence. - * - * Returns: 1 always. - * Args: ctx: a secp256k1 context object. - * Out: output: a pointer to a 65-byte (if compressed==0) or 33-byte (if - * compressed==1) byte array to place the serialized key - * in. - * In/Out: outputlen: a pointer to an integer which is initially set to the - * size of output, and is overwritten with the written - * size. - * In: pubkey: a pointer to a secp256k1_pubkey containing an - * initialized public key. - * flags: SECP256K1_EC_COMPRESSED if serialization should be in - * compressed format, otherwise SECP256K1_EC_UNCOMPRESSED. - */ -SECP256K1_API int secp256k1_ec_pubkey_serialize( - const secp256k1_context* ctx, - unsigned char *output, - size_t *outputlen, - const secp256k1_pubkey* pubkey, - unsigned int flags -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Parse an ECDSA signature in compact (64 bytes) format. - * - * Returns: 1 when the signature could be parsed, 0 otherwise. - * Args: ctx: a secp256k1 context object - * Out: sig: a pointer to a signature object - * In: input64: a pointer to the 64-byte array to parse - * - * The signature must consist of a 32-byte big endian R value, followed by a - * 32-byte big endian S value. If R or S fall outside of [0..order-1], the - * encoding is invalid. R and S with value 0 are allowed in the encoding. - * - * After the call, sig will always be initialized. If parsing failed or R or - * S are zero, the resulting sig value is guaranteed to fail validation for any - * message and public key. - */ -SECP256K1_API int secp256k1_ecdsa_signature_parse_compact( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, - const unsigned char *input64 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Parse a DER ECDSA signature. - * - * Returns: 1 when the signature could be parsed, 0 otherwise. - * Args: ctx: a secp256k1 context object - * Out: sig: a pointer to a signature object - * In: input: a pointer to the signature to be parsed - * inputlen: the length of the array pointed to be input - * - * This function will accept any valid DER encoded signature, even if the - * encoded numbers are out of range. - * - * After the call, sig will always be initialized. If parsing failed or the - * encoded numbers are out of range, signature validation with it is - * guaranteed to fail for every message and public key. - */ -SECP256K1_API int secp256k1_ecdsa_signature_parse_der( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, - const unsigned char *input, - size_t inputlen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Serialize an ECDSA signature in DER format. - * - * Returns: 1 if enough space was available to serialize, 0 otherwise - * Args: ctx: a secp256k1 context object - * Out: output: a pointer to an array to store the DER serialization - * In/Out: outputlen: a pointer to a length integer. Initially, this integer - * should be set to the length of output. After the call - * it will be set to the length of the serialization (even - * if 0 was returned). - * In: sig: a pointer to an initialized signature object - */ -SECP256K1_API int secp256k1_ecdsa_signature_serialize_der( - const secp256k1_context* ctx, - unsigned char *output, - size_t *outputlen, - const secp256k1_ecdsa_signature* sig -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Serialize an ECDSA signature in compact (64 byte) format. - * - * Returns: 1 - * Args: ctx: a secp256k1 context object - * Out: output64: a pointer to a 64-byte array to store the compact serialization - * In: sig: a pointer to an initialized signature object - * - * See secp256k1_ecdsa_signature_parse_compact for details about the encoding. - */ -SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact( - const secp256k1_context* ctx, - unsigned char *output64, - const secp256k1_ecdsa_signature* sig -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Verify an ECDSA signature. - * - * Returns: 1: correct signature - * 0: incorrect or unparseable signature - * Args: ctx: a secp256k1 context object, initialized for verification. - * In: sig: the signature being verified (cannot be NULL) - * msg32: the 32-byte message hash being verified (cannot be NULL) - * pubkey: pointer to an initialized public key to verify with (cannot be NULL) - * - * To avoid accepting malleable signatures, only ECDSA signatures in lower-S - * form are accepted. - * - * If you need to accept ECDSA signatures from sources that do not obey this - * rule, apply secp256k1_ecdsa_signature_normalize to the signature prior to - * validation, but be aware that doing so results in malleable signatures. - * - * For details, see the comments for that function. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( - const secp256k1_context* ctx, - const secp256k1_ecdsa_signature *sig, - const unsigned char *msg32, - const secp256k1_pubkey *pubkey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Convert a signature to a normalized lower-S form. - * - * Returns: 1 if sigin was not normalized, 0 if it already was. - * Args: ctx: a secp256k1 context object - * Out: sigout: a pointer to a signature to fill with the normalized form, - * or copy if the input was already normalized. (can be NULL if - * you're only interested in whether the input was already - * normalized). - * In: sigin: a pointer to a signature to check/normalize (cannot be NULL, - * can be identical to sigout) - * - * With ECDSA a third-party can forge a second distinct signature of the same - * message, given a single initial signature, but without knowing the key. This - * is done by negating the S value modulo the order of the curve, 'flipping' - * the sign of the random point R which is not included in the signature. - * - * Forgery of the same message isn't universally problematic, but in systems - * where message malleability or uniqueness of signatures is important this can - * cause issues. This forgery can be blocked by all verifiers forcing signers - * to use a normalized form. - * - * The lower-S form reduces the size of signatures slightly on average when - * variable length encodings (such as DER) are used and is cheap to verify, - * making it a good choice. Security of always using lower-S is assured because - * anyone can trivially modify a signature after the fact to enforce this - * property anyway. - * - * The lower S value is always between 0x1 and - * 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, - * inclusive. - * - * No other forms of ECDSA malleability are known and none seem likely, but - * there is no formal proof that ECDSA, even with this additional restriction, - * is free of other malleability. Commonly used serialization schemes will also - * accept various non-unique encodings, so care should be taken when this - * property is required for an application. - * - * The secp256k1_ecdsa_sign function will by default create signatures in the - * lower-S form, and secp256k1_ecdsa_verify will not accept others. In case - * signatures come from a system that cannot enforce this property, - * secp256k1_ecdsa_signature_normalize must be called before verification. - */ -SECP256K1_API int secp256k1_ecdsa_signature_normalize( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature *sigout, - const secp256k1_ecdsa_signature *sigin -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3); - -/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function. - * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of - * extra entropy. - */ -SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; - -/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */ -SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default; - -/** Create an ECDSA signature. - * - * Returns: 1: signature created - * 0: the nonce generation function failed, or the private key was invalid. - * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) - * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) - * - * The created signature is always in lower-S form. See - * secp256k1_ecdsa_signature_normalize for more details. - */ -SECP256K1_API int secp256k1_ecdsa_sign( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature *sig, - const unsigned char *msg32, - const unsigned char *seckey, - secp256k1_nonce_function noncefp, - const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Verify an ECDSA secret key. - * - * Returns: 1: secret key is valid - * 0: secret key is invalid - * Args: ctx: pointer to a context object (cannot be NULL) - * In: seckey: pointer to a 32-byte secret key (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify( - const secp256k1_context* ctx, - const unsigned char *seckey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); - -/** Compute the public key for a secret key. - * - * Returns: 1: secret was valid, public key stores - * 0: secret was invalid, try again - * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * Out: pubkey: pointer to the created public key (cannot be NULL) - * In: seckey: pointer to a 32-byte private key (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *seckey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Negates a private key in place. - * - * Returns: 1 always - * Args: ctx: pointer to a context object - * In/Out: seckey: pointer to the 32-byte private key to be negated (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate( - const secp256k1_context* ctx, - unsigned char *seckey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); - -/** Negates a public key in place. - * - * Returns: 1 always - * Args: ctx: pointer to a context object - * In/Out: pubkey: pointer to the public key to be negated (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); - -/** Tweak a private key by adding tweak to it. - * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for - * uniformly random 32-byte arrays, or if the resulting private key - * would be invalid (only when the tweak is the complement of the - * private key). 1 otherwise. - * Args: ctx: pointer to a context object (cannot be NULL). - * In/Out: seckey: pointer to a 32-byte private key. - * In: tweak: pointer to a 32-byte tweak. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( - const secp256k1_context* ctx, - unsigned char *seckey, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Tweak a public key by adding tweak times the generator to it. - * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for - * uniformly random 32-byte arrays, or if the resulting public key - * would be invalid (only when the tweak is the complement of the - * corresponding private key). 1 otherwise. - * Args: ctx: pointer to a context object initialized for validation - * (cannot be NULL). - * In/Out: pubkey: pointer to a public key object. - * In: tweak: pointer to a 32-byte tweak. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Tweak a private key by multiplying it by a tweak. - * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for - * uniformly random 32-byte arrays, or equal to zero. 1 otherwise. - * Args: ctx: pointer to a context object (cannot be NULL). - * In/Out: seckey: pointer to a 32-byte private key. - * In: tweak: pointer to a 32-byte tweak. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( - const secp256k1_context* ctx, - unsigned char *seckey, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Tweak a public key by multiplying it by a tweak value. - * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for - * uniformly random 32-byte arrays, or equal to zero. 1 otherwise. - * Args: ctx: pointer to a context object initialized for validation - * (cannot be NULL). - * In/Out: pubkey: pointer to a public key obkect. - * In: tweak: pointer to a 32-byte tweak. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Updates the context randomization to protect against side-channel leakage. - * Returns: 1: randomization successfully updated - * 0: error - * Args: ctx: pointer to a context object (cannot be NULL) - * In: seed32: pointer to a 32-byte random seed (NULL resets to initial state) - * - * While secp256k1 code is written to be constant-time no matter what secret - * values are, it's possible that a future compiler may output code which isn't, - * and also that the CPU may not emit the same radio frequencies or draw the same - * amount power for all values. - * - * This function provides a seed which is combined into the blinding value: that - * blinding value is added before each multiplication (and removed afterwards) so - * that it does not affect function results, but shields against attacks which - * rely on any input-dependent behaviour. - * - * You should call this after secp256k1_context_create or - * secp256k1_context_clone, and may call this repeatedly afterwards. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize( - secp256k1_context* ctx, - const unsigned char *seed32 -) SECP256K1_ARG_NONNULL(1); - -/** Add a number of public keys together. - * Returns: 1: the sum of the public keys is valid. - * 0: the sum of the public keys is not valid. - * Args: ctx: pointer to a context object - * Out: out: pointer to a public key object for placing the resulting public key - * (cannot be NULL) - * In: ins: pointer to array of pointers to public keys (cannot be NULL) - * n: the number of public keys to add together (must be at least 1) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine( - const secp256k1_context* ctx, - secp256k1_pubkey *out, - const secp256k1_pubkey * const * ins, - size_t n -) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Compute an EC Diffie-Hellman secret in constant time - * Returns: 1: exponentiation was successful - * 0: scalar was invalid (zero or overflow) - * Args: ctx: pointer to a context object (cannot be NULL) - * Out: result: a 32-byte array which will be populated by an ECDH - * secret computed from the point and scalar - * In: pubkey: a pointer to a secp256k1_pubkey containing an - * initialized public key - * privkey: a 32-byte scalar with which to multiply the point - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( - const secp256k1_context* ctx, - unsigned char *result, - const secp256k1_pubkey *pubkey, - const unsigned char *privkey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Opaque data structured that holds a parsed ECDSA signature, - * supporting pubkey recovery. - * - * The exact representation of data inside is implementation defined and not - * guaranteed to be portable between different platforms or versions. It is - * however guaranteed to be 65 bytes in size, and can be safely copied/moved. - * If you need to convert to a format suitable for storage or transmission, use - * the secp256k1_ecdsa_signature_serialize_* and - * secp256k1_ecdsa_signature_parse_* functions. - * - * Furthermore, it is guaranteed that identical signatures (including their - * recoverability) will have identical representation, so they can be - * memcmp'ed. - */ -typedef struct { - unsigned char data[65]; -} secp256k1_ecdsa_recoverable_signature; - -/** Parse a compact ECDSA signature (64 bytes + recovery id). - * - * Returns: 1 when the signature could be parsed, 0 otherwise - * Args: ctx: a secp256k1 context object - * Out: sig: a pointer to a signature object - * In: input64: a pointer to a 64-byte compact signature - * recid: the recovery id (0, 1, 2 or 3) - */ -SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact( - const secp256k1_context* ctx, - secp256k1_ecdsa_recoverable_signature* sig, - const unsigned char *input64, - int recid -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Convert a recoverable signature into a normal signature. - * - * Returns: 1 - * Out: sig: a pointer to a normal signature (cannot be NULL). - * In: sigin: a pointer to a recoverable signature (cannot be NULL). - */ -SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, - const secp256k1_ecdsa_recoverable_signature* sigin -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Serialize an ECDSA signature in compact format (64 bytes + recovery id). - * - * Returns: 1 - * Args: ctx: a secp256k1 context object - * Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL) - * recid: a pointer to an integer to hold the recovery id (can be NULL). - * In: sig: a pointer to an initialized signature object (cannot be NULL) - */ -SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact( - const secp256k1_context* ctx, - unsigned char *output64, - int *recid, - const secp256k1_ecdsa_recoverable_signature* sig -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Create a recoverable ECDSA signature. - * - * Returns: 1: signature created - * 0: the nonce generation function failed, or the private key was invalid. - * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) - * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) - */ -SECP256K1_API int secp256k1_ecdsa_sign_recoverable( - const secp256k1_context* ctx, - secp256k1_ecdsa_recoverable_signature *sig, - const unsigned char *msg32, - const unsigned char *seckey, - secp256k1_nonce_function noncefp, - const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Recover an ECDSA public key from a signature. - * - * Returns: 1: public key successfully recovered (which guarantees a correct signature). - * 0: otherwise. - * Args: ctx: pointer to a context object, initialized for verification (cannot be NULL) - * Out: pubkey: pointer to the recovered public key (cannot be NULL) - * In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL) - * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const secp256k1_ecdsa_recoverable_signature *sig, - const unsigned char *msg32 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -#ifdef __cplusplus -} -#endif - -#endif /* SECP256K1_H */ diff --git a/Sources/secp256k1/src/ecdsa.h b/Sources/secp256k1/src/ecdsa.h deleted file mode 100644 index 80590c7..0000000 --- a/Sources/secp256k1/src/ecdsa.h +++ /dev/null @@ -1,21 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECDSA_H -#define SECP256K1_ECDSA_H - -#include - -#include "scalar.h" -#include "group.h" -#include "ecmult.h" - -static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size); -static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s); -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message); -static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid); - -#endif /* SECP256K1_ECDSA_H */ diff --git a/Sources/secp256k1/src/ecdsa_impl.h b/Sources/secp256k1/src/ecdsa_impl.h deleted file mode 100644 index c340004..0000000 --- a/Sources/secp256k1/src/ecdsa_impl.h +++ /dev/null @@ -1,313 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - - -#ifndef SECP256K1_ECDSA_IMPL_H -#define SECP256K1_ECDSA_IMPL_H - -#include "scalar.h" -#include "field.h" -#include "group.h" -#include "ecmult.h" -#include "ecmult_gen.h" -#include "ecdsa.h" - -/** Group order for secp256k1 defined as 'n' in "Standards for Efficient Cryptography" (SEC2) 2.7.1 - * sage: for t in xrange(1023, -1, -1): - * .. p = 2**256 - 2**32 - t - * .. if p.is_prime(): - * .. print '%x'%p - * .. break - * 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f' - * sage: a = 0 - * sage: b = 7 - * sage: F = FiniteField (p) - * sage: '%x' % (EllipticCurve ([F (a), F (b)]).order()) - * 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141' - */ -static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST( - 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, - 0xBAAEDCE6UL, 0xAF48A03BUL, 0xBFD25E8CUL, 0xD0364141UL -); - -/** Difference between field and order, values 'p' and 'n' values defined in - * "Standards for Efficient Cryptography" (SEC2) 2.7.1. - * sage: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F - * sage: a = 0 - * sage: b = 7 - * sage: F = FiniteField (p) - * sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order()) - * '14551231950b75fc4402da1722fc9baee' - */ -static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( - 0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL -); - -static int secp256k1_der_read_len(const unsigned char **sigp, const unsigned char *sigend) { - int lenleft, b1; - size_t ret = 0; - if (*sigp >= sigend) { - return -1; - } - b1 = *((*sigp)++); - if (b1 == 0xFF) { - /* X.690-0207 8.1.3.5.c the value 0xFF shall not be used. */ - return -1; - } - if ((b1 & 0x80) == 0) { - /* X.690-0207 8.1.3.4 short form length octets */ - return b1; - } - if (b1 == 0x80) { - /* Indefinite length is not allowed in DER. */ - return -1; - } - /* X.690-207 8.1.3.5 long form length octets */ - lenleft = b1 & 0x7F; - if (lenleft > sigend - *sigp) { - return -1; - } - if (**sigp == 0) { - /* Not the shortest possible length encoding. */ - return -1; - } - if ((size_t)lenleft > sizeof(size_t)) { - /* The resulting length would exceed the range of a size_t, so - * certainly longer than the passed array size. - */ - return -1; - } - while (lenleft > 0) { - ret = (ret << 8) | **sigp; - if (ret + lenleft > (size_t)(sigend - *sigp)) { - /* Result exceeds the length of the passed array. */ - return -1; - } - (*sigp)++; - lenleft--; - } - if (ret < 128) { - /* Not the shortest possible length encoding. */ - return -1; - } - return ret; -} - -static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char **sig, const unsigned char *sigend) { - int overflow = 0; - unsigned char ra[32] = {0}; - int rlen; - - if (*sig == sigend || **sig != 0x02) { - /* Not a primitive integer (X.690-0207 8.3.1). */ - return 0; - } - (*sig)++; - rlen = secp256k1_der_read_len(sig, sigend); - if (rlen <= 0 || (*sig) + rlen > sigend) { - /* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */ - return 0; - } - if (**sig == 0x00 && rlen > 1 && (((*sig)[1]) & 0x80) == 0x00) { - /* Excessive 0x00 padding. */ - return 0; - } - if (**sig == 0xFF && rlen > 1 && (((*sig)[1]) & 0x80) == 0x80) { - /* Excessive 0xFF padding. */ - return 0; - } - if ((**sig & 0x80) == 0x80) { - /* Negative. */ - overflow = 1; - } - while (rlen > 0 && **sig == 0) { - /* Skip leading zero bytes */ - rlen--; - (*sig)++; - } - if (rlen > 32) { - overflow = 1; - } - if (!overflow) { - memcpy(ra + 32 - rlen, *sig, rlen); - secp256k1_scalar_set_b32(r, ra, &overflow); - } - if (overflow) { - secp256k1_scalar_set_int(r, 0); - } - (*sig) += rlen; - return 1; -} - -static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *rr, secp256k1_scalar *rs, const unsigned char *sig, size_t size) { - const unsigned char *sigend = sig + size; - int rlen; - if (sig == sigend || *(sig++) != 0x30) { - /* The encoding doesn't start with a constructed sequence (X.690-0207 8.9.1). */ - return 0; - } - rlen = secp256k1_der_read_len(&sig, sigend); - if (rlen < 0 || sig + rlen > sigend) { - /* Tuple exceeds bounds */ - return 0; - } - if (sig + rlen != sigend) { - /* Garbage after tuple. */ - return 0; - } - - if (!secp256k1_der_parse_integer(rr, &sig, sigend)) { - return 0; - } - if (!secp256k1_der_parse_integer(rs, &sig, sigend)) { - return 0; - } - - if (sig != sigend) { - /* Trailing garbage inside tuple. */ - return 0; - } - - return 1; -} - -static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar* ar, const secp256k1_scalar* as) { - unsigned char r[33] = {0}, s[33] = {0}; - unsigned char *rp = r, *sp = s; - size_t lenR = 33, lenS = 33; - secp256k1_scalar_get_b32(&r[1], ar); - secp256k1_scalar_get_b32(&s[1], as); - while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; } - while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; } - if (*size < 6+lenS+lenR) { - *size = 6 + lenS + lenR; - return 0; - } - *size = 6 + lenS + lenR; - sig[0] = 0x30; - sig[1] = 4 + lenS + lenR; - sig[2] = 0x02; - sig[3] = lenR; - memcpy(sig+4, rp, lenR); - sig[4+lenR] = 0x02; - sig[5+lenR] = lenS; - memcpy(sig+lenR+6, sp, lenS); - return 1; -} - -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) { - unsigned char c[32]; - secp256k1_scalar sn, u1, u2; -#if !defined(EXHAUSTIVE_TEST_ORDER) - secp256k1_fe xr; -#endif - secp256k1_gej pubkeyj; - secp256k1_gej pr; - - if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { - return 0; - } - - secp256k1_scalar_inverse_var(&sn, sigs); - secp256k1_scalar_mul(&u1, &sn, message); - secp256k1_scalar_mul(&u2, &sn, sigr); - secp256k1_gej_set_ge(&pubkeyj, pubkey); - secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1); - if (secp256k1_gej_is_infinity(&pr)) { - return 0; - } - -#if defined(EXHAUSTIVE_TEST_ORDER) -{ - secp256k1_scalar computed_r; - secp256k1_ge pr_ge; - secp256k1_ge_set_gej(&pr_ge, &pr); - secp256k1_fe_normalize(&pr_ge.x); - - secp256k1_fe_get_b32(c, &pr_ge.x); - secp256k1_scalar_set_b32(&computed_r, c, NULL); - return secp256k1_scalar_eq(sigr, &computed_r); -} -#else - secp256k1_scalar_get_b32(c, sigr); - secp256k1_fe_set_b32(&xr, c); - - /** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n) - * in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p), - * compute the remainder modulo n, and compare it to xr. However: - * - * xr == X(pr) mod n - * <=> exists h. (xr + h * n < p && xr + h * n == X(pr)) - * [Since 2 * n > p, h can only be 0 or 1] - * <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr)) - * [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p] - * <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p) - * [Multiplying both sides of the equations by pr.z^2 mod p] - * <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x) - * - * Thus, we can avoid the inversion, but we have to check both cases separately. - * secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test. - */ - if (secp256k1_gej_eq_x_var(&xr, &pr)) { - /* xr * pr.z^2 mod p == pr.x, so the signature is valid. */ - return 1; - } - if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_const_p_minus_order) >= 0) { - /* xr + n >= p, so we can skip testing the second case. */ - return 0; - } - secp256k1_fe_add(&xr, &secp256k1_ecdsa_const_order_as_fe); - if (secp256k1_gej_eq_x_var(&xr, &pr)) { - /* (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid. */ - return 1; - } - return 0; -#endif -} - -static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid) { - unsigned char b[32]; - secp256k1_gej rp; - secp256k1_ge r; - secp256k1_scalar n; - int overflow = 0; - - secp256k1_ecmult_gen(ctx, &rp, nonce); - secp256k1_ge_set_gej(&r, &rp); - secp256k1_fe_normalize(&r.x); - secp256k1_fe_normalize(&r.y); - secp256k1_fe_get_b32(b, &r.x); - secp256k1_scalar_set_b32(sigr, b, &overflow); - /* These two conditions should be checked before calling */ - VERIFY_CHECK(!secp256k1_scalar_is_zero(sigr)); - VERIFY_CHECK(overflow == 0); - - if (recid) { - /* The overflow condition is cryptographically unreachable as hitting it requires finding the discrete log - * of some P where P.x >= order, and only 1 in about 2^127 points meet this criteria. - */ - *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0); - } - secp256k1_scalar_mul(&n, sigr, seckey); - secp256k1_scalar_add(&n, &n, message); - secp256k1_scalar_inverse(sigs, nonce); - secp256k1_scalar_mul(sigs, sigs, &n); - secp256k1_scalar_clear(&n); - secp256k1_gej_clear(&rp); - secp256k1_ge_clear(&r); - if (secp256k1_scalar_is_zero(sigs)) { - return 0; - } - if (secp256k1_scalar_is_high(sigs)) { - secp256k1_scalar_negate(sigs, sigs); - if (recid) { - *recid ^= 1; - } - } - return 1; -} - -#endif /* SECP256K1_ECDSA_IMPL_H */ diff --git a/Sources/secp256k1/src/eckey.h b/Sources/secp256k1/src/eckey.h deleted file mode 100644 index b621f1e..0000000 --- a/Sources/secp256k1/src/eckey.h +++ /dev/null @@ -1,25 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECKEY_H -#define SECP256K1_ECKEY_H - -#include - -#include "group.h" -#include "scalar.h" -#include "ecmult.h" -#include "ecmult_gen.h" - -static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size); -static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed); - -static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak); -static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); -static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak); -static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); - -#endif /* SECP256K1_ECKEY_H */ diff --git a/Sources/secp256k1/src/eckey_impl.h b/Sources/secp256k1/src/eckey_impl.h deleted file mode 100644 index 1ab9a68..0000000 --- a/Sources/secp256k1/src/eckey_impl.h +++ /dev/null @@ -1,100 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECKEY_IMPL_H -#define SECP256K1_ECKEY_IMPL_H - -#include "eckey.h" - -#include "scalar.h" -#include "field.h" -#include "group.h" -#include "ecmult_gen.h" - -static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) { - if (size == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) { - secp256k1_fe x; - return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD); - } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) { - secp256k1_fe x, y; - if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { - return 0; - } - secp256k1_ge_set_xy(elem, &x, &y); - if ((pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD) && - secp256k1_fe_is_odd(&y) != (pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { - return 0; - } - return secp256k1_ge_is_valid_var(elem); - } else { - return 0; - } -} - -static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) { - if (secp256k1_ge_is_infinity(elem)) { - return 0; - } - secp256k1_fe_normalize_var(&elem->x); - secp256k1_fe_normalize_var(&elem->y); - secp256k1_fe_get_b32(&pub[1], &elem->x); - if (compressed) { - *size = 33; - pub[0] = secp256k1_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN; - } else { - *size = 65; - pub[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED; - secp256k1_fe_get_b32(&pub[33], &elem->y); - } - return 1; -} - -static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) { - secp256k1_scalar_add(key, key, tweak); - if (secp256k1_scalar_is_zero(key)) { - return 0; - } - return 1; -} - -static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { - secp256k1_gej pt; - secp256k1_scalar one; - secp256k1_gej_set_ge(&pt, key); - secp256k1_scalar_set_int(&one, 1); - secp256k1_ecmult(ctx, &pt, &pt, &one, tweak); - - if (secp256k1_gej_is_infinity(&pt)) { - return 0; - } - secp256k1_ge_set_gej(key, &pt); - return 1; -} - -static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak) { - if (secp256k1_scalar_is_zero(tweak)) { - return 0; - } - - secp256k1_scalar_mul(key, key, tweak); - return 1; -} - -static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { - secp256k1_scalar zero; - secp256k1_gej pt; - if (secp256k1_scalar_is_zero(tweak)) { - return 0; - } - - secp256k1_scalar_set_int(&zero, 0); - secp256k1_gej_set_ge(&pt, key); - secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero); - secp256k1_ge_set_gej(key, &pt); - return 1; -} - -#endif /* SECP256K1_ECKEY_IMPL_H */ diff --git a/Sources/secp256k1/src/ecmult.h b/Sources/secp256k1/src/ecmult.h deleted file mode 100644 index ea1cd8a..0000000 --- a/Sources/secp256k1/src/ecmult.h +++ /dev/null @@ -1,47 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECMULT_H -#define SECP256K1_ECMULT_H - -#include "num.h" -#include "group.h" -#include "scalar.h" -#include "scratch.h" - -typedef struct { - /* For accelerating the computation of a*P + b*G: */ - secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */ -#ifdef USE_ENDOMORPHISM - secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */ -#endif -} secp256k1_ecmult_context; - -static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx); -static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb); -static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, - const secp256k1_ecmult_context *src, const secp256k1_callback *cb); -static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx); -static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx); - -/** Double multiply: R = na*A + ng*G */ -static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng); - -typedef int (secp256k1_ecmult_multi_callback)(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data); - -/** - * Multi-multiply: R = inp_g_sc * G + sum_i ni * Ai. - * Chooses the right algorithm for a given number of points and scratch space - * size. Resets and overwrites the given scratch space. If the points do not - * fit in the scratch space the algorithm is repeatedly run with batches of - * points. - * Returns: 1 on success (including when inp_g_sc is NULL and n is 0) - * 0 if there is not enough scratch space for a single point or - * callback returns 0 - */ -static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n); - -#endif /* SECP256K1_ECMULT_H */ diff --git a/Sources/secp256k1/src/ecmult_const.h b/Sources/secp256k1/src/ecmult_const.h deleted file mode 100644 index d4804b8..0000000 --- a/Sources/secp256k1/src/ecmult_const.h +++ /dev/null @@ -1,17 +0,0 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECMULT_CONST_H -#define SECP256K1_ECMULT_CONST_H - -#include "scalar.h" -#include "group.h" - -/* Here `bits` should be set to the maximum bitlength of the _absolute value_ of `q`, plus - * one because we internally sometimes add 2 to the number during the WNAF conversion. */ -static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q, int bits); - -#endif /* SECP256K1_ECMULT_CONST_H */ diff --git a/Sources/secp256k1/src/ecmult_const_impl.h b/Sources/secp256k1/src/ecmult_const_impl.h deleted file mode 100644 index 8411752..0000000 --- a/Sources/secp256k1/src/ecmult_const_impl.h +++ /dev/null @@ -1,257 +0,0 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECMULT_CONST_IMPL_H -#define SECP256K1_ECMULT_CONST_IMPL_H - -#include "scalar.h" -#include "group.h" -#include "ecmult_const.h" -#include "ecmult_impl.h" - -/* This is like `ECMULT_TABLE_GET_GE` but is constant time */ -#define ECMULT_CONST_TABLE_GET_GE(r,pre,n,w) do { \ - int m; \ - int abs_n = (n) * (((n) > 0) * 2 - 1); \ - int idx_n = abs_n / 2; \ - secp256k1_fe neg_y; \ - VERIFY_CHECK(((n) & 1) == 1); \ - VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ - VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ - VERIFY_SETUP(secp256k1_fe_clear(&(r)->x)); \ - VERIFY_SETUP(secp256k1_fe_clear(&(r)->y)); \ - for (m = 0; m < ECMULT_TABLE_SIZE(w); m++) { \ - /* This loop is used to avoid secret data in array indices. See - * the comment in ecmult_gen_impl.h for rationale. */ \ - secp256k1_fe_cmov(&(r)->x, &(pre)[m].x, m == idx_n); \ - secp256k1_fe_cmov(&(r)->y, &(pre)[m].y, m == idx_n); \ - } \ - (r)->infinity = 0; \ - secp256k1_fe_negate(&neg_y, &(r)->y, 1); \ - secp256k1_fe_cmov(&(r)->y, &neg_y, (n) != abs_n); \ -} while(0) - - -/** Convert a number to WNAF notation. - * The number becomes represented by sum(2^{wi} * wnaf[i], i=0..WNAF_SIZE(w)+1) - return_val. - * It has the following guarantees: - * - each wnaf[i] an odd integer between -(1 << w) and (1 << w) - * - each wnaf[i] is nonzero - * - the number of words set is always WNAF_SIZE(w) + 1 - * - * Adapted from `The Width-w NAF Method Provides Small Memory and Fast Elliptic Scalar - * Multiplications Secure against Side Channel Attacks`, Okeya and Tagaki. M. Joye (Ed.) - * CT-RSA 2003, LNCS 2612, pp. 328-443, 2003. Springer-Verlagy Berlin Heidelberg 2003 - * - * Numbers reference steps of `Algorithm SPA-resistant Width-w NAF with Odd Scalar` on pp. 335 - */ -static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w, int size) { - int global_sign; - int skew = 0; - int word = 0; - - /* 1 2 3 */ - int u_last; - int u; - - int flip; - int bit; - secp256k1_scalar neg_s; - int not_neg_one; - /* Note that we cannot handle even numbers by negating them to be odd, as is - * done in other implementations, since if our scalars were specified to have - * width < 256 for performance reasons, their negations would have width 256 - * and we'd lose any performance benefit. Instead, we use a technique from - * Section 4.2 of the Okeya/Tagaki paper, which is to add either 1 (for even) - * or 2 (for odd) to the number we are encoding, returning a skew value indicating - * this, and having the caller compensate after doing the multiplication. - * - * In fact, we _do_ want to negate numbers to minimize their bit-lengths (and in - * particular, to ensure that the outputs from the endomorphism-split fit into - * 128 bits). If we negate, the parity of our number flips, inverting which of - * {1, 2} we want to add to the scalar when ensuring that it's odd. Further - * complicating things, -1 interacts badly with `secp256k1_scalar_cadd_bit` and - * we need to special-case it in this logic. */ - flip = secp256k1_scalar_is_high(&s); - /* We add 1 to even numbers, 2 to odd ones, noting that negation flips parity */ - bit = flip ^ !secp256k1_scalar_is_even(&s); - /* We check for negative one, since adding 2 to it will cause an overflow */ - secp256k1_scalar_negate(&neg_s, &s); - not_neg_one = !secp256k1_scalar_is_one(&neg_s); - secp256k1_scalar_cadd_bit(&s, bit, not_neg_one); - /* If we had negative one, flip == 1, s.d[0] == 0, bit == 1, so caller expects - * that we added two to it and flipped it. In fact for -1 these operations are - * identical. We only flipped, but since skewing is required (in the sense that - * the skew must be 1 or 2, never zero) and flipping is not, we need to change - * our flags to claim that we only skewed. */ - global_sign = secp256k1_scalar_cond_negate(&s, flip); - global_sign *= not_neg_one * 2 - 1; - skew = 1 << bit; - - /* 4 */ - u_last = secp256k1_scalar_shr_int(&s, w); - while (word * w < size) { - int sign; - int even; - - /* 4.1 4.4 */ - u = secp256k1_scalar_shr_int(&s, w); - /* 4.2 */ - even = ((u & 1) == 0); - sign = 2 * (u_last > 0) - 1; - u += sign * even; - u_last -= sign * even * (1 << w); - - /* 4.3, adapted for global sign change */ - wnaf[word++] = u_last * global_sign; - - u_last = u; - } - wnaf[word] = u * global_sign; - - VERIFY_CHECK(secp256k1_scalar_is_zero(&s)); - VERIFY_CHECK(word == WNAF_SIZE_BITS(size, w)); - return skew; -} - -static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *scalar, int size) { - secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_ge tmpa; - secp256k1_fe Z; - - int skew_1; -#ifdef USE_ENDOMORPHISM - secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; - int wnaf_lam[1 + WNAF_SIZE(WINDOW_A - 1)]; - int skew_lam; - secp256k1_scalar q_1, q_lam; -#endif - int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)]; - - int i; - secp256k1_scalar sc = *scalar; - - /* build wnaf representation for q. */ - int rsize = size; -#ifdef USE_ENDOMORPHISM - if (size > 128) { - rsize = 128; - /* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */ - secp256k1_scalar_split_lambda(&q_1, &q_lam, &sc); - skew_1 = secp256k1_wnaf_const(wnaf_1, q_1, WINDOW_A - 1, 128); - skew_lam = secp256k1_wnaf_const(wnaf_lam, q_lam, WINDOW_A - 1, 128); - } else -#endif - { - skew_1 = secp256k1_wnaf_const(wnaf_1, sc, WINDOW_A - 1, size); -#ifdef USE_ENDOMORPHISM - skew_lam = 0; -#endif - } - - /* Calculate odd multiples of a. - * All multiples are brought to the same Z 'denominator', which is stored - * in Z. Due to secp256k1' isomorphism we can do all operations pretending - * that the Z coordinate was 1, use affine addition formulae, and correct - * the Z coordinate of the result once at the end. - */ - secp256k1_gej_set_ge(r, a); - secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, &Z, r); - for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { - secp256k1_fe_normalize_weak(&pre_a[i].y); - } -#ifdef USE_ENDOMORPHISM - if (size > 128) { - for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { - secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]); - } - } -#endif - - /* first loop iteration (separated out so we can directly set r, rather - * than having it start at infinity, get doubled several times, then have - * its new value added to it) */ - i = wnaf_1[WNAF_SIZE_BITS(rsize, WINDOW_A - 1)]; - VERIFY_CHECK(i != 0); - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); - secp256k1_gej_set_ge(r, &tmpa); -#ifdef USE_ENDOMORPHISM - if (size > 128) { - i = wnaf_lam[WNAF_SIZE_BITS(rsize, WINDOW_A - 1)]; - VERIFY_CHECK(i != 0); - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, i, WINDOW_A); - secp256k1_gej_add_ge(r, r, &tmpa); - } -#endif - /* remaining loop iterations */ - for (i = WNAF_SIZE_BITS(rsize, WINDOW_A - 1) - 1; i >= 0; i--) { - int n; - int j; - for (j = 0; j < WINDOW_A - 1; ++j) { - secp256k1_gej_double_nonzero(r, r, NULL); - } - - n = wnaf_1[i]; - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); - VERIFY_CHECK(n != 0); - secp256k1_gej_add_ge(r, r, &tmpa); -#ifdef USE_ENDOMORPHISM - if (size > 128) { - n = wnaf_lam[i]; - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); - VERIFY_CHECK(n != 0); - secp256k1_gej_add_ge(r, r, &tmpa); - } -#endif - } - - secp256k1_fe_mul(&r->z, &r->z, &Z); - - { - /* Correct for wNAF skew */ - secp256k1_ge correction = *a; - secp256k1_ge_storage correction_1_stor; -#ifdef USE_ENDOMORPHISM - secp256k1_ge_storage correction_lam_stor; -#endif - secp256k1_ge_storage a2_stor; - secp256k1_gej tmpj; - secp256k1_gej_set_ge(&tmpj, &correction); - secp256k1_gej_double_var(&tmpj, &tmpj, NULL); - secp256k1_ge_set_gej(&correction, &tmpj); - secp256k1_ge_to_storage(&correction_1_stor, a); -#ifdef USE_ENDOMORPHISM - if (size > 128) { - secp256k1_ge_to_storage(&correction_lam_stor, a); - } -#endif - secp256k1_ge_to_storage(&a2_stor, &correction); - - /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */ - secp256k1_ge_storage_cmov(&correction_1_stor, &a2_stor, skew_1 == 2); -#ifdef USE_ENDOMORPHISM - if (size > 128) { - secp256k1_ge_storage_cmov(&correction_lam_stor, &a2_stor, skew_lam == 2); - } -#endif - - /* Apply the correction */ - secp256k1_ge_from_storage(&correction, &correction_1_stor); - secp256k1_ge_neg(&correction, &correction); - secp256k1_gej_add_ge(r, r, &correction); - -#ifdef USE_ENDOMORPHISM - if (size > 128) { - secp256k1_ge_from_storage(&correction, &correction_lam_stor); - secp256k1_ge_neg(&correction, &correction); - secp256k1_ge_mul_lambda(&correction, &correction); - secp256k1_gej_add_ge(r, r, &correction); - } -#endif - } -} - -#endif /* SECP256K1_ECMULT_CONST_IMPL_H */ diff --git a/Sources/secp256k1/src/ecmult_gen.h b/Sources/secp256k1/src/ecmult_gen.h deleted file mode 100644 index 7564b70..0000000 --- a/Sources/secp256k1/src/ecmult_gen.h +++ /dev/null @@ -1,43 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECMULT_GEN_H -#define SECP256K1_ECMULT_GEN_H - -#include "scalar.h" -#include "group.h" - -typedef struct { - /* For accelerating the computation of a*G: - * To harden against timing attacks, use the following mechanism: - * * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63. - * * Compute sum(n_i * 16^i * G + U_i, i=0..63), where: - * * U_i = U * 2^i (for i=0..62) - * * U_i = U * (1-2^63) (for i=63) - * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0..63) = 0. - * For each i, and each of the 16 possible values of n_i, (n_i * 16^i * G + U_i) is - * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63). - * None of the resulting prec group elements have a known scalar, and neither do any of - * the intermediate sums while computing a*G. - */ - secp256k1_ge_storage (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ - secp256k1_scalar blind; - secp256k1_gej initial; -} secp256k1_ecmult_gen_context; - -static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context* ctx); -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, const secp256k1_callback* cb); -static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, - const secp256k1_ecmult_gen_context* src, const secp256k1_callback* cb); -static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); -static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx); - -/** Multiply with the generator: R = a*G */ -static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); - -static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32); - -#endif /* SECP256K1_ECMULT_GEN_H */ diff --git a/Sources/secp256k1/src/ecmult_gen_impl.h b/Sources/secp256k1/src/ecmult_gen_impl.h deleted file mode 100644 index 714f02e..0000000 --- a/Sources/secp256k1/src/ecmult_gen_impl.h +++ /dev/null @@ -1,210 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECMULT_GEN_IMPL_H -#define SECP256K1_ECMULT_GEN_IMPL_H - -#include "scalar.h" -#include "group.h" -#include "ecmult_gen.h" -#include "hash_impl.h" -#ifdef USE_ECMULT_STATIC_PRECOMPUTATION -#include "ecmult_static_context.h" -#endif -static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context *ctx) { - ctx->prec = NULL; -} - -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx, const secp256k1_callback* cb) { -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - secp256k1_ge prec[1024]; - secp256k1_gej gj; - secp256k1_gej nums_gej; - int i, j; -#endif - - if (ctx->prec != NULL) { - return; - } -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - ctx->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*ctx->prec)); - - /* get the generator */ - secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); - - /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ - { - static const unsigned char nums_b32[33] = "The scalar for this x is unknown"; - secp256k1_fe nums_x; - secp256k1_ge nums_ge; - int r; - r = secp256k1_fe_set_b32(&nums_x, nums_b32); - (void)r; - VERIFY_CHECK(r); - r = secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0); - (void)r; - VERIFY_CHECK(r); - secp256k1_gej_set_ge(&nums_gej, &nums_ge); - /* Add G to make the bits in x uniformly distributed. */ - secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g, NULL); - } - - /* compute prec. */ - { - secp256k1_gej precj[1024]; /* Jacobian versions of prec. */ - secp256k1_gej gbase; - secp256k1_gej numsbase; - gbase = gj; /* 16^j * G */ - numsbase = nums_gej; /* 2^j * nums. */ - for (j = 0; j < 64; j++) { - /* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */ - precj[j*16] = numsbase; - for (i = 1; i < 16; i++) { - secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase, NULL); - } - /* Multiply gbase by 16. */ - for (i = 0; i < 4; i++) { - secp256k1_gej_double_var(&gbase, &gbase, NULL); - } - /* Multiply numbase by 2. */ - secp256k1_gej_double_var(&numsbase, &numsbase, NULL); - if (j == 62) { - /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ - secp256k1_gej_neg(&numsbase, &numsbase); - secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL); - } - } - secp256k1_ge_set_all_gej_var(prec, precj, 1024, cb); - } - for (j = 0; j < 64; j++) { - for (i = 0; i < 16; i++) { - secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]); - } - } -#else - (void)cb; - ctx->prec = (secp256k1_ge_storage (*)[64][16])secp256k1_ecmult_static_context; -#endif - secp256k1_ecmult_gen_blind(ctx, NULL); -} - -static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx) { - return ctx->prec != NULL; -} - -static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, - const secp256k1_ecmult_gen_context *src, const secp256k1_callback* cb) { - if (src->prec == NULL) { - dst->prec = NULL; - } else { -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - dst->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*dst->prec)); - memcpy(dst->prec, src->prec, sizeof(*dst->prec)); -#else - (void)cb; - dst->prec = src->prec; -#endif - dst->initial = src->initial; - dst->blind = src->blind; - } -} - -static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) { -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - free(ctx->prec); -#endif - secp256k1_scalar_clear(&ctx->blind); - secp256k1_gej_clear(&ctx->initial); - ctx->prec = NULL; -} - -static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) { - secp256k1_ge add; - secp256k1_ge_storage adds; - secp256k1_scalar gnb; - int bits; - int i, j; - memset(&adds, 0, sizeof(adds)); - *r = ctx->initial; - /* Blind scalar/point multiplication by computing (n-b)G + bG instead of nG. */ - secp256k1_scalar_add(&gnb, gn, &ctx->blind); - add.infinity = 0; - for (j = 0; j < 64; j++) { - bits = secp256k1_scalar_get_bits(&gnb, j * 4, 4); - for (i = 0; i < 16; i++) { - /** This uses a conditional move to avoid any secret data in array indexes. - * _Any_ use of secret indexes has been demonstrated to result in timing - * sidechannels, even when the cache-line access patterns are uniform. - * See also: - * "A word of warning", CHES 2013 Rump Session, by Daniel J. Bernstein and Peter Schwabe - * (https://cryptojedi.org/peter/data/chesrump-20130822.pdf) and - * "Cache Attacks and Countermeasures: the Case of AES", RSA 2006, - * by Dag Arne Osvik, Adi Shamir, and Eran Tromer - * (http://www.tau.ac.il/~tromer/papers/cache.pdf) - */ - secp256k1_ge_storage_cmov(&adds, &(*ctx->prec)[j][i], i == bits); - } - secp256k1_ge_from_storage(&add, &adds); - secp256k1_gej_add_ge(r, r, &add); - } - bits = 0; - secp256k1_ge_clear(&add); - secp256k1_scalar_clear(&gnb); -} - -/* Setup blinding values for secp256k1_ecmult_gen. */ -static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32) { - secp256k1_scalar b; - secp256k1_gej gb; - secp256k1_fe s; - unsigned char nonce32[32]; - secp256k1_rfc6979_hmac_sha256 rng; - int retry; - unsigned char keydata[64] = {0}; - if (seed32 == NULL) { - /* When seed is NULL, reset the initial point and blinding value. */ - secp256k1_gej_set_ge(&ctx->initial, &secp256k1_ge_const_g); - secp256k1_gej_neg(&ctx->initial, &ctx->initial); - secp256k1_scalar_set_int(&ctx->blind, 1); - } - /* The prior blinding value (if not reset) is chained forward by including it in the hash. */ - secp256k1_scalar_get_b32(nonce32, &ctx->blind); - /** Using a CSPRNG allows a failure free interface, avoids needing large amounts of random data, - * and guards against weak or adversarial seeds. This is a simpler and safer interface than - * asking the caller for blinding values directly and expecting them to retry on failure. - */ - memcpy(keydata, nonce32, 32); - if (seed32 != NULL) { - memcpy(keydata + 32, seed32, 32); - } - secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, seed32 ? 64 : 32); - memset(keydata, 0, sizeof(keydata)); - /* Retry for out of range results to achieve uniformity. */ - do { - secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); - retry = !secp256k1_fe_set_b32(&s, nonce32); - retry |= secp256k1_fe_is_zero(&s); - } while (retry); /* This branch true is cryptographically unreachable. Requires sha256_hmac output > Fp. */ - /* Randomize the projection to defend against multiplier sidechannels. */ - secp256k1_gej_rescale(&ctx->initial, &s); - secp256k1_fe_clear(&s); - do { - secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); - secp256k1_scalar_set_b32(&b, nonce32, &retry); - /* A blinding value of 0 works, but would undermine the projection hardening. */ - retry |= secp256k1_scalar_is_zero(&b); - } while (retry); /* This branch true is cryptographically unreachable. Requires sha256_hmac output > order. */ - secp256k1_rfc6979_hmac_sha256_finalize(&rng); - memset(nonce32, 0, 32); - secp256k1_ecmult_gen(ctx, &gb, &b); - secp256k1_scalar_negate(&b, &b); - ctx->blind = b; - ctx->initial = gb; - secp256k1_scalar_clear(&b); - secp256k1_gej_clear(&gb); -} - -#endif /* SECP256K1_ECMULT_GEN_IMPL_H */ diff --git a/Sources/secp256k1/src/ecmult_impl.h b/Sources/secp256k1/src/ecmult_impl.h deleted file mode 100644 index d5fb6c5..0000000 --- a/Sources/secp256k1/src/ecmult_impl.h +++ /dev/null @@ -1,1027 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra, Jonas Nick * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php. * - *****************************************************************************/ - -#ifndef SECP256K1_ECMULT_IMPL_H -#define SECP256K1_ECMULT_IMPL_H - -#include -#include - -#include "group.h" -#include "scalar.h" -#include "ecmult.h" - -#if defined(EXHAUSTIVE_TEST_ORDER) -/* We need to lower these values for exhaustive tests because - * the tables cannot have infinities in them (this breaks the - * affine-isomorphism stuff which tracks z-ratios) */ -# if EXHAUSTIVE_TEST_ORDER > 128 -# define WINDOW_A 5 -# define WINDOW_G 8 -# elif EXHAUSTIVE_TEST_ORDER > 8 -# define WINDOW_A 4 -# define WINDOW_G 4 -# else -# define WINDOW_A 2 -# define WINDOW_G 2 -# endif -#else -/* optimal for 128-bit and 256-bit exponents. */ -#define WINDOW_A 5 -/** larger numbers may result in slightly better performance, at the cost of - exponentially larger precomputed tables. */ -#ifdef USE_ENDOMORPHISM -/** Two tables for window size 15: 1.375 MiB. */ -#define WINDOW_G 15 -#else -/** One table for window size 16: 1.375 MiB. */ -#define WINDOW_G 16 -#endif -#endif - -#ifdef USE_ENDOMORPHISM - #define WNAF_BITS 128 -#else - #define WNAF_BITS 256 -#endif -#define WNAF_SIZE_BITS(bits, w) (((bits) + (w) - 1) / (w)) -#define WNAF_SIZE(w) WNAF_SIZE_BITS(WNAF_BITS, w) - -/** The number of entries a table with precomputed multiples needs to have. */ -#define ECMULT_TABLE_SIZE(w) (1 << ((w)-2)) - -/* The number of objects allocated on the scratch space for ecmult_multi algorithms */ -#define PIPPENGER_SCRATCH_OBJECTS 6 -#define STRAUSS_SCRATCH_OBJECTS 6 - -#define PIPPENGER_MAX_BUCKET_WINDOW 12 - -/* Minimum number of points for which pippenger_wnaf is faster than strauss wnaf */ -#ifdef USE_ENDOMORPHISM - #define ECMULT_PIPPENGER_THRESHOLD 88 -#else - #define ECMULT_PIPPENGER_THRESHOLD 160 -#endif - -#ifdef USE_ENDOMORPHISM - #define ECMULT_MAX_POINTS_PER_BATCH 5000000 -#else - #define ECMULT_MAX_POINTS_PER_BATCH 10000000 -#endif - -/** Fill a table 'prej' with precomputed odd multiples of a. Prej will contain - * the values [1*a,3*a,...,(2*n-1)*a], so it space for n values. zr[0] will - * contain prej[0].z / a.z. The other zr[i] values = prej[i].z / prej[i-1].z. - * Prej's Z values are undefined, except for the last value. - */ -static void secp256k1_ecmult_odd_multiples_table(int n, secp256k1_gej *prej, secp256k1_fe *zr, const secp256k1_gej *a) { - secp256k1_gej d; - secp256k1_ge a_ge, d_ge; - int i; - - VERIFY_CHECK(!a->infinity); - - secp256k1_gej_double_var(&d, a, NULL); - - /* - * Perform the additions on an isomorphism where 'd' is affine: drop the z coordinate - * of 'd', and scale the 1P starting value's x/y coordinates without changing its z. - */ - d_ge.x = d.x; - d_ge.y = d.y; - d_ge.infinity = 0; - - secp256k1_ge_set_gej_zinv(&a_ge, a, &d.z); - prej[0].x = a_ge.x; - prej[0].y = a_ge.y; - prej[0].z = a->z; - prej[0].infinity = 0; - - zr[0] = d.z; - for (i = 1; i < n; i++) { - secp256k1_gej_add_ge_var(&prej[i], &prej[i-1], &d_ge, &zr[i]); - } - - /* - * Each point in 'prej' has a z coordinate too small by a factor of 'd.z'. Only - * the final point's z coordinate is actually used though, so just update that. - */ - secp256k1_fe_mul(&prej[n-1].z, &prej[n-1].z, &d.z); -} - -/** Fill a table 'pre' with precomputed odd multiples of a. - * - * There are two versions of this function: - * - secp256k1_ecmult_odd_multiples_table_globalz_windowa which brings its - * resulting point set to a single constant Z denominator, stores the X and Y - * coordinates as ge_storage points in pre, and stores the global Z in rz. - * It only operates on tables sized for WINDOW_A wnaf multiples. - * - secp256k1_ecmult_odd_multiples_table_storage_var, which converts its - * resulting point set to actually affine points, and stores those in pre. - * It operates on tables of any size, but uses heap-allocated temporaries. - * - * To compute a*P + b*G, we compute a table for P using the first function, - * and for G using the second (which requires an inverse, but it only needs to - * happen once). - */ -static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge *pre, secp256k1_fe *globalz, const secp256k1_gej *a) { - secp256k1_gej prej[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_fe zr[ECMULT_TABLE_SIZE(WINDOW_A)]; - - /* Compute the odd multiples in Jacobian form. */ - secp256k1_ecmult_odd_multiples_table(ECMULT_TABLE_SIZE(WINDOW_A), prej, zr, a); - /* Bring them to the same Z denominator. */ - secp256k1_ge_globalz_set_table_gej(ECMULT_TABLE_SIZE(WINDOW_A), pre, globalz, prej, zr); -} - -static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, secp256k1_ge_storage *pre, const secp256k1_gej *a, const secp256k1_callback *cb) { - secp256k1_gej *prej = (secp256k1_gej*)checked_malloc(cb, sizeof(secp256k1_gej) * n); - secp256k1_ge *prea = (secp256k1_ge*)checked_malloc(cb, sizeof(secp256k1_ge) * n); - secp256k1_fe *zr = (secp256k1_fe*)checked_malloc(cb, sizeof(secp256k1_fe) * n); - int i; - - /* Compute the odd multiples in Jacobian form. */ - secp256k1_ecmult_odd_multiples_table(n, prej, zr, a); - /* Convert them in batch to affine coordinates. */ - secp256k1_ge_set_table_gej_var(prea, prej, zr, n); - /* Convert them to compact storage form. */ - for (i = 0; i < n; i++) { - secp256k1_ge_to_storage(&pre[i], &prea[i]); - } - - free(prea); - free(prej); - free(zr); -} - -/** The following two macro retrieves a particular odd multiple from a table - * of precomputed multiples. */ -#define ECMULT_TABLE_GET_GE(r,pre,n,w) do { \ - VERIFY_CHECK(((n) & 1) == 1); \ - VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ - VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ - if ((n) > 0) { \ - *(r) = (pre)[((n)-1)/2]; \ - } else { \ - secp256k1_ge_neg((r), &(pre)[(-(n)-1)/2]); \ - } \ -} while(0) - -#define ECMULT_TABLE_GET_GE_STORAGE(r,pre,n,w) do { \ - VERIFY_CHECK(((n) & 1) == 1); \ - VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ - VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ - if ((n) > 0) { \ - secp256k1_ge_from_storage((r), &(pre)[((n)-1)/2]); \ - } else { \ - secp256k1_ge_from_storage((r), &(pre)[(-(n)-1)/2]); \ - secp256k1_ge_neg((r), (r)); \ - } \ -} while(0) - -static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx) { - ctx->pre_g = NULL; -#ifdef USE_ENDOMORPHISM - ctx->pre_g_128 = NULL; -#endif -} - -static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb) { - secp256k1_gej gj; - - if (ctx->pre_g != NULL) { - return; - } - - /* get the generator */ - secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); - - ctx->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); - - /* precompute the tables with odd multiples */ - secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g, &gj, cb); - -#ifdef USE_ENDOMORPHISM - { - secp256k1_gej g_128j; - int i; - - ctx->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); - - /* calculate 2^128*generator */ - g_128j = gj; - for (i = 0; i < 128; i++) { - secp256k1_gej_double_var(&g_128j, &g_128j, NULL); - } - secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g_128, &g_128j, cb); - } -#endif -} - -static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, - const secp256k1_ecmult_context *src, const secp256k1_callback *cb) { - if (src->pre_g == NULL) { - dst->pre_g = NULL; - } else { - size_t size = sizeof((*dst->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G); - dst->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, size); - memcpy(dst->pre_g, src->pre_g, size); - } -#ifdef USE_ENDOMORPHISM - if (src->pre_g_128 == NULL) { - dst->pre_g_128 = NULL; - } else { - size_t size = sizeof((*dst->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G); - dst->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, size); - memcpy(dst->pre_g_128, src->pre_g_128, size); - } -#endif -} - -static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx) { - return ctx->pre_g != NULL; -} - -static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx) { - free(ctx->pre_g); -#ifdef USE_ENDOMORPHISM - free(ctx->pre_g_128); -#endif - secp256k1_ecmult_context_init(ctx); -} - -/** Convert a number to WNAF notation. The number becomes represented by sum(2^i * wnaf[i], i=0..bits), - * with the following guarantees: - * - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1) - * - two non-zero entries in wnaf are separated by at least w-1 zeroes. - * - the number of set values in wnaf is returned. This number is at most 256, and at most one more - * than the number of bits in the (absolute value) of the input. - */ -static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a, int w) { - secp256k1_scalar s = *a; - int last_set_bit = -1; - int bit = 0; - int sign = 1; - int carry = 0; - - VERIFY_CHECK(wnaf != NULL); - VERIFY_CHECK(0 <= len && len <= 256); - VERIFY_CHECK(a != NULL); - VERIFY_CHECK(2 <= w && w <= 31); - - memset(wnaf, 0, len * sizeof(wnaf[0])); - - if (secp256k1_scalar_get_bits(&s, 255, 1)) { - secp256k1_scalar_negate(&s, &s); - sign = -1; - } - - while (bit < len) { - int now; - int word; - if (secp256k1_scalar_get_bits(&s, bit, 1) == (unsigned int)carry) { - bit++; - continue; - } - - now = w; - if (now > len - bit) { - now = len - bit; - } - - word = secp256k1_scalar_get_bits_var(&s, bit, now) + carry; - - carry = (word >> (w-1)) & 1; - word -= carry << w; - - wnaf[bit] = sign * word; - last_set_bit = bit; - - bit += now; - } -#ifdef VERIFY - CHECK(carry == 0); - while (bit < 256) { - CHECK(secp256k1_scalar_get_bits(&s, bit++, 1) == 0); - } -#endif - return last_set_bit + 1; -} - -struct secp256k1_strauss_point_state { -#ifdef USE_ENDOMORPHISM - secp256k1_scalar na_1, na_lam; - int wnaf_na_1[130]; - int wnaf_na_lam[130]; - int bits_na_1; - int bits_na_lam; -#else - int wnaf_na[256]; - int bits_na; -#endif - size_t input_pos; -}; - -struct secp256k1_strauss_state { - secp256k1_gej* prej; - secp256k1_fe* zr; - secp256k1_ge* pre_a; -#ifdef USE_ENDOMORPHISM - secp256k1_ge* pre_a_lam; -#endif - struct secp256k1_strauss_point_state* ps; -}; - -static void secp256k1_ecmult_strauss_wnaf(const secp256k1_ecmult_context *ctx, const struct secp256k1_strauss_state *state, secp256k1_gej *r, int num, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) { - secp256k1_ge tmpa; - secp256k1_fe Z; -#ifdef USE_ENDOMORPHISM - /* Splitted G factors. */ - secp256k1_scalar ng_1, ng_128; - int wnaf_ng_1[129]; - int bits_ng_1 = 0; - int wnaf_ng_128[129]; - int bits_ng_128 = 0; -#else - int wnaf_ng[256]; - int bits_ng = 0; -#endif - int i; - int bits = 0; - int np; - int no = 0; - - for (np = 0; np < num; ++np) { - if (secp256k1_scalar_is_zero(&na[np]) || secp256k1_gej_is_infinity(&a[np])) { - continue; - } - state->ps[no].input_pos = np; -#ifdef USE_ENDOMORPHISM - /* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */ - secp256k1_scalar_split_lambda(&state->ps[no].na_1, &state->ps[no].na_lam, &na[np]); - - /* build wnaf representation for na_1 and na_lam. */ - state->ps[no].bits_na_1 = secp256k1_ecmult_wnaf(state->ps[no].wnaf_na_1, 130, &state->ps[no].na_1, WINDOW_A); - state->ps[no].bits_na_lam = secp256k1_ecmult_wnaf(state->ps[no].wnaf_na_lam, 130, &state->ps[no].na_lam, WINDOW_A); - VERIFY_CHECK(state->ps[no].bits_na_1 <= 130); - VERIFY_CHECK(state->ps[no].bits_na_lam <= 130); - if (state->ps[no].bits_na_1 > bits) { - bits = state->ps[no].bits_na_1; - } - if (state->ps[no].bits_na_lam > bits) { - bits = state->ps[no].bits_na_lam; - } -#else - /* build wnaf representation for na. */ - state->ps[no].bits_na = secp256k1_ecmult_wnaf(state->ps[no].wnaf_na, 256, &na[np], WINDOW_A); - if (state->ps[no].bits_na > bits) { - bits = state->ps[no].bits_na; - } -#endif - ++no; - } - - /* Calculate odd multiples of a. - * All multiples are brought to the same Z 'denominator', which is stored - * in Z. Due to secp256k1' isomorphism we can do all operations pretending - * that the Z coordinate was 1, use affine addition formulae, and correct - * the Z coordinate of the result once at the end. - * The exception is the precomputed G table points, which are actually - * affine. Compared to the base used for other points, they have a Z ratio - * of 1/Z, so we can use secp256k1_gej_add_zinv_var, which uses the same - * isomorphism to efficiently add with a known Z inverse. - */ - if (no > 0) { - /* Compute the odd multiples in Jacobian form. */ - secp256k1_ecmult_odd_multiples_table(ECMULT_TABLE_SIZE(WINDOW_A), state->prej, state->zr, &a[state->ps[0].input_pos]); - for (np = 1; np < no; ++np) { - secp256k1_gej tmp = a[state->ps[np].input_pos]; -#ifdef VERIFY - secp256k1_fe_normalize_var(&(state->prej[(np - 1) * ECMULT_TABLE_SIZE(WINDOW_A) + ECMULT_TABLE_SIZE(WINDOW_A) - 1].z)); -#endif - secp256k1_gej_rescale(&tmp, &(state->prej[(np - 1) * ECMULT_TABLE_SIZE(WINDOW_A) + ECMULT_TABLE_SIZE(WINDOW_A) - 1].z)); - secp256k1_ecmult_odd_multiples_table(ECMULT_TABLE_SIZE(WINDOW_A), state->prej + np * ECMULT_TABLE_SIZE(WINDOW_A), state->zr + np * ECMULT_TABLE_SIZE(WINDOW_A), &tmp); - secp256k1_fe_mul(state->zr + np * ECMULT_TABLE_SIZE(WINDOW_A), state->zr + np * ECMULT_TABLE_SIZE(WINDOW_A), &(a[state->ps[np].input_pos].z)); - } - /* Bring them to the same Z denominator. */ - secp256k1_ge_globalz_set_table_gej(ECMULT_TABLE_SIZE(WINDOW_A) * no, state->pre_a, &Z, state->prej, state->zr); - } else { - secp256k1_fe_set_int(&Z, 1); - } - -#ifdef USE_ENDOMORPHISM - for (np = 0; np < no; ++np) { - for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { - secp256k1_ge_mul_lambda(&state->pre_a_lam[np * ECMULT_TABLE_SIZE(WINDOW_A) + i], &state->pre_a[np * ECMULT_TABLE_SIZE(WINDOW_A) + i]); - } - } - - if (ng) { - /* split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit) */ - secp256k1_scalar_split_128(&ng_1, &ng_128, ng); - - /* Build wnaf representation for ng_1 and ng_128 */ - bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, 129, &ng_1, WINDOW_G); - bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, 129, &ng_128, WINDOW_G); - if (bits_ng_1 > bits) { - bits = bits_ng_1; - } - if (bits_ng_128 > bits) { - bits = bits_ng_128; - } - } -#else - if (ng) { - bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, 256, ng, WINDOW_G); - if (bits_ng > bits) { - bits = bits_ng; - } - } -#endif - - secp256k1_gej_set_infinity(r); - - for (i = bits - 1; i >= 0; i--) { - int n; - secp256k1_gej_double_var(r, r, NULL); -#ifdef USE_ENDOMORPHISM - for (np = 0; np < no; ++np) { - if (i < state->ps[np].bits_na_1 && (n = state->ps[np].wnaf_na_1[i])) { - ECMULT_TABLE_GET_GE(&tmpa, state->pre_a + np * ECMULT_TABLE_SIZE(WINDOW_A), n, WINDOW_A); - secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); - } - if (i < state->ps[np].bits_na_lam && (n = state->ps[np].wnaf_na_lam[i])) { - ECMULT_TABLE_GET_GE(&tmpa, state->pre_a_lam + np * ECMULT_TABLE_SIZE(WINDOW_A), n, WINDOW_A); - secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); - } - } - if (i < bits_ng_1 && (n = wnaf_ng_1[i])) { - ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G); - secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); - } - if (i < bits_ng_128 && (n = wnaf_ng_128[i])) { - ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g_128, n, WINDOW_G); - secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); - } -#else - for (np = 0; np < no; ++np) { - if (i < state->ps[np].bits_na && (n = state->ps[np].wnaf_na[i])) { - ECMULT_TABLE_GET_GE(&tmpa, state->pre_a + np * ECMULT_TABLE_SIZE(WINDOW_A), n, WINDOW_A); - secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); - } - } - if (i < bits_ng && (n = wnaf_ng[i])) { - ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G); - secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); - } -#endif - } - - if (!r->infinity) { - secp256k1_fe_mul(&r->z, &r->z, &Z); - } -} - -static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) { - secp256k1_gej prej[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_fe zr[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; - struct secp256k1_strauss_point_state ps[1]; -#ifdef USE_ENDOMORPHISM - secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; -#endif - struct secp256k1_strauss_state state; - - state.prej = prej; - state.zr = zr; - state.pre_a = pre_a; -#ifdef USE_ENDOMORPHISM - state.pre_a_lam = pre_a_lam; -#endif - state.ps = ps; - secp256k1_ecmult_strauss_wnaf(ctx, &state, r, 1, a, na, ng); -} - -static size_t secp256k1_strauss_scratch_size(size_t n_points) { -#ifdef USE_ENDOMORPHISM - static const size_t point_size = (2 * sizeof(secp256k1_ge) + sizeof(secp256k1_gej) + sizeof(secp256k1_fe)) * ECMULT_TABLE_SIZE(WINDOW_A) + sizeof(struct secp256k1_strauss_point_state) + sizeof(secp256k1_gej) + sizeof(secp256k1_scalar); -#else - static const size_t point_size = (sizeof(secp256k1_ge) + sizeof(secp256k1_gej) + sizeof(secp256k1_fe)) * ECMULT_TABLE_SIZE(WINDOW_A) + sizeof(struct secp256k1_strauss_point_state) + sizeof(secp256k1_gej) + sizeof(secp256k1_scalar); -#endif - return n_points*point_size; -} - -static int secp256k1_ecmult_strauss_batch(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n_points, size_t cb_offset) { - secp256k1_gej* points; - secp256k1_scalar* scalars; - struct secp256k1_strauss_state state; - size_t i; - - secp256k1_gej_set_infinity(r); - if (inp_g_sc == NULL && n_points == 0) { - return 1; - } - - if (!secp256k1_scratch_allocate_frame(scratch, secp256k1_strauss_scratch_size(n_points), STRAUSS_SCRATCH_OBJECTS)) { - return 0; - } - points = (secp256k1_gej*)secp256k1_scratch_alloc(scratch, n_points * sizeof(secp256k1_gej)); - scalars = (secp256k1_scalar*)secp256k1_scratch_alloc(scratch, n_points * sizeof(secp256k1_scalar)); - state.prej = (secp256k1_gej*)secp256k1_scratch_alloc(scratch, n_points * ECMULT_TABLE_SIZE(WINDOW_A) * sizeof(secp256k1_gej)); - state.zr = (secp256k1_fe*)secp256k1_scratch_alloc(scratch, n_points * ECMULT_TABLE_SIZE(WINDOW_A) * sizeof(secp256k1_fe)); -#ifdef USE_ENDOMORPHISM - state.pre_a = (secp256k1_ge*)secp256k1_scratch_alloc(scratch, n_points * 2 * ECMULT_TABLE_SIZE(WINDOW_A) * sizeof(secp256k1_ge)); - state.pre_a_lam = state.pre_a + n_points * ECMULT_TABLE_SIZE(WINDOW_A); -#else - state.pre_a = (secp256k1_ge*)secp256k1_scratch_alloc(scratch, n_points * ECMULT_TABLE_SIZE(WINDOW_A) * sizeof(secp256k1_ge)); -#endif - state.ps = (struct secp256k1_strauss_point_state*)secp256k1_scratch_alloc(scratch, n_points * sizeof(struct secp256k1_strauss_point_state)); - - for (i = 0; i < n_points; i++) { - secp256k1_ge point; - if (!cb(&scalars[i], &point, i+cb_offset, cbdata)) { - secp256k1_scratch_deallocate_frame(scratch); - return 0; - } - secp256k1_gej_set_ge(&points[i], &point); - } - secp256k1_ecmult_strauss_wnaf(ctx, &state, r, n_points, points, scalars, inp_g_sc); - secp256k1_scratch_deallocate_frame(scratch); - return 1; -} - -/* Wrapper for secp256k1_ecmult_multi_func interface */ -static int secp256k1_ecmult_strauss_batch_single(const secp256k1_ecmult_context *actx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n) { - return secp256k1_ecmult_strauss_batch(actx, scratch, r, inp_g_sc, cb, cbdata, n, 0); -} - -static size_t secp256k1_strauss_max_points(secp256k1_scratch *scratch) { - return secp256k1_scratch_max_allocation(scratch, STRAUSS_SCRATCH_OBJECTS) / secp256k1_strauss_scratch_size(1); -} - -/** Convert a number to WNAF notation. - * The number becomes represented by sum(2^{wi} * wnaf[i], i=0..WNAF_SIZE(w)+1) - return_val. - * It has the following guarantees: - * - each wnaf[i] is either 0 or an odd integer between -(1 << w) and (1 << w) - * - the number of words set is always WNAF_SIZE(w) - * - the returned skew is 0 or 1 - */ -static int secp256k1_wnaf_fixed(int *wnaf, const secp256k1_scalar *s, int w) { - int skew = 0; - int pos; - int max_pos; - int last_w; - const secp256k1_scalar *work = s; - - if (secp256k1_scalar_is_zero(s)) { - for (pos = 0; pos < WNAF_SIZE(w); pos++) { - wnaf[pos] = 0; - } - return 0; - } - - if (secp256k1_scalar_is_even(s)) { - skew = 1; - } - - wnaf[0] = secp256k1_scalar_get_bits_var(work, 0, w) + skew; - /* Compute last window size. Relevant when window size doesn't divide the - * number of bits in the scalar */ - last_w = WNAF_BITS - (WNAF_SIZE(w) - 1) * w; - - /* Store the position of the first nonzero word in max_pos to allow - * skipping leading zeros when calculating the wnaf. */ - for (pos = WNAF_SIZE(w) - 1; pos > 0; pos--) { - int val = secp256k1_scalar_get_bits_var(work, pos * w, pos == WNAF_SIZE(w)-1 ? last_w : w); - if(val != 0) { - break; - } - wnaf[pos] = 0; - } - max_pos = pos; - pos = 1; - - while (pos <= max_pos) { - int val = secp256k1_scalar_get_bits_var(work, pos * w, pos == WNAF_SIZE(w)-1 ? last_w : w); - if ((val & 1) == 0) { - wnaf[pos - 1] -= (1 << w); - wnaf[pos] = (val + 1); - } else { - wnaf[pos] = val; - } - /* Set a coefficient to zero if it is 1 or -1 and the proceeding digit - * is strictly negative or strictly positive respectively. Only change - * coefficients at previous positions because above code assumes that - * wnaf[pos - 1] is odd. - */ - if (pos >= 2 && ((wnaf[pos - 1] == 1 && wnaf[pos - 2] < 0) || (wnaf[pos - 1] == -1 && wnaf[pos - 2] > 0))) { - if (wnaf[pos - 1] == 1) { - wnaf[pos - 2] += 1 << w; - } else { - wnaf[pos - 2] -= 1 << w; - } - wnaf[pos - 1] = 0; - } - ++pos; - } - - return skew; -} - -struct secp256k1_pippenger_point_state { - int skew_na; - size_t input_pos; -}; - -struct secp256k1_pippenger_state { - int *wnaf_na; - struct secp256k1_pippenger_point_state* ps; -}; - -/* - * pippenger_wnaf computes the result of a multi-point multiplication as - * follows: The scalars are brought into wnaf with n_wnaf elements each. Then - * for every i < n_wnaf, first each point is added to a "bucket" corresponding - * to the point's wnaf[i]. Second, the buckets are added together such that - * r += 1*bucket[0] + 3*bucket[1] + 5*bucket[2] + ... - */ -static int secp256k1_ecmult_pippenger_wnaf(secp256k1_gej *buckets, int bucket_window, struct secp256k1_pippenger_state *state, secp256k1_gej *r, const secp256k1_scalar *sc, const secp256k1_ge *pt, size_t num) { - size_t n_wnaf = WNAF_SIZE(bucket_window+1); - size_t np; - size_t no = 0; - int i; - int j; - - for (np = 0; np < num; ++np) { - if (secp256k1_scalar_is_zero(&sc[np]) || secp256k1_ge_is_infinity(&pt[np])) { - continue; - } - state->ps[no].input_pos = np; - state->ps[no].skew_na = secp256k1_wnaf_fixed(&state->wnaf_na[no*n_wnaf], &sc[np], bucket_window+1); - no++; - } - secp256k1_gej_set_infinity(r); - - if (no == 0) { - return 1; - } - - for (i = n_wnaf - 1; i >= 0; i--) { - secp256k1_gej running_sum; - - for(j = 0; j < ECMULT_TABLE_SIZE(bucket_window+2); j++) { - secp256k1_gej_set_infinity(&buckets[j]); - } - - for (np = 0; np < no; ++np) { - int n = state->wnaf_na[np*n_wnaf + i]; - struct secp256k1_pippenger_point_state point_state = state->ps[np]; - secp256k1_ge tmp; - int idx; - - if (i == 0) { - /* correct for wnaf skew */ - int skew = point_state.skew_na; - if (skew) { - secp256k1_ge_neg(&tmp, &pt[point_state.input_pos]); - secp256k1_gej_add_ge_var(&buckets[0], &buckets[0], &tmp, NULL); - } - } - if (n > 0) { - idx = (n - 1)/2; - secp256k1_gej_add_ge_var(&buckets[idx], &buckets[idx], &pt[point_state.input_pos], NULL); - } else if (n < 0) { - idx = -(n + 1)/2; - secp256k1_ge_neg(&tmp, &pt[point_state.input_pos]); - secp256k1_gej_add_ge_var(&buckets[idx], &buckets[idx], &tmp, NULL); - } - } - - for(j = 0; j < bucket_window; j++) { - secp256k1_gej_double_var(r, r, NULL); - } - - secp256k1_gej_set_infinity(&running_sum); - /* Accumulate the sum: bucket[0] + 3*bucket[1] + 5*bucket[2] + 7*bucket[3] + ... - * = bucket[0] + bucket[1] + bucket[2] + bucket[3] + ... - * + 2 * (bucket[1] + 2*bucket[2] + 3*bucket[3] + ...) - * using an intermediate running sum: - * running_sum = bucket[0] + bucket[1] + bucket[2] + ... - * - * The doubling is done implicitly by deferring the final window doubling (of 'r'). - */ - for(j = ECMULT_TABLE_SIZE(bucket_window+2) - 1; j > 0; j--) { - secp256k1_gej_add_var(&running_sum, &running_sum, &buckets[j], NULL); - secp256k1_gej_add_var(r, r, &running_sum, NULL); - } - - secp256k1_gej_add_var(&running_sum, &running_sum, &buckets[0], NULL); - secp256k1_gej_double_var(r, r, NULL); - secp256k1_gej_add_var(r, r, &running_sum, NULL); - } - return 1; -} - -/** - * Returns optimal bucket_window (number of bits of a scalar represented by a - * set of buckets) for a given number of points. - */ -static int secp256k1_pippenger_bucket_window(size_t n) { -#ifdef USE_ENDOMORPHISM - if (n <= 1) { - return 1; - } else if (n <= 4) { - return 2; - } else if (n <= 20) { - return 3; - } else if (n <= 57) { - return 4; - } else if (n <= 136) { - return 5; - } else if (n <= 235) { - return 6; - } else if (n <= 1260) { - return 7; - } else if (n <= 4420) { - return 9; - } else if (n <= 7880) { - return 10; - } else if (n <= 16050) { - return 11; - } else { - return PIPPENGER_MAX_BUCKET_WINDOW; - } -#else - if (n <= 1) { - return 1; - } else if (n <= 11) { - return 2; - } else if (n <= 45) { - return 3; - } else if (n <= 100) { - return 4; - } else if (n <= 275) { - return 5; - } else if (n <= 625) { - return 6; - } else if (n <= 1850) { - return 7; - } else if (n <= 3400) { - return 8; - } else if (n <= 9630) { - return 9; - } else if (n <= 17900) { - return 10; - } else if (n <= 32800) { - return 11; - } else { - return PIPPENGER_MAX_BUCKET_WINDOW; - } -#endif -} - -/** - * Returns the maximum optimal number of points for a bucket_window. - */ -static size_t secp256k1_pippenger_bucket_window_inv(int bucket_window) { - switch(bucket_window) { -#ifdef USE_ENDOMORPHISM - case 1: return 1; - case 2: return 4; - case 3: return 20; - case 4: return 57; - case 5: return 136; - case 6: return 235; - case 7: return 1260; - case 8: return 1260; - case 9: return 4420; - case 10: return 7880; - case 11: return 16050; - case PIPPENGER_MAX_BUCKET_WINDOW: return SIZE_MAX; -#else - case 1: return 1; - case 2: return 11; - case 3: return 45; - case 4: return 100; - case 5: return 275; - case 6: return 625; - case 7: return 1850; - case 8: return 3400; - case 9: return 9630; - case 10: return 17900; - case 11: return 32800; - case PIPPENGER_MAX_BUCKET_WINDOW: return SIZE_MAX; -#endif - } - return 0; -} - - -#ifdef USE_ENDOMORPHISM -SECP256K1_INLINE static void secp256k1_ecmult_endo_split(secp256k1_scalar *s1, secp256k1_scalar *s2, secp256k1_ge *p1, secp256k1_ge *p2) { - secp256k1_scalar tmp = *s1; - secp256k1_scalar_split_lambda(s1, s2, &tmp); - secp256k1_ge_mul_lambda(p2, p1); - - if (secp256k1_scalar_is_high(s1)) { - secp256k1_scalar_negate(s1, s1); - secp256k1_ge_neg(p1, p1); - } - if (secp256k1_scalar_is_high(s2)) { - secp256k1_scalar_negate(s2, s2); - secp256k1_ge_neg(p2, p2); - } -} -#endif - -/** - * Returns the scratch size required for a given number of points (excluding - * base point G) without considering alignment. - */ -static size_t secp256k1_pippenger_scratch_size(size_t n_points, int bucket_window) { -#ifdef USE_ENDOMORPHISM - size_t entries = 2*n_points + 2; -#else - size_t entries = n_points + 1; -#endif - size_t entry_size = sizeof(secp256k1_ge) + sizeof(secp256k1_scalar) + sizeof(struct secp256k1_pippenger_point_state) + (WNAF_SIZE(bucket_window+1)+1)*sizeof(int); - return ((1<ps = (struct secp256k1_pippenger_point_state *) secp256k1_scratch_alloc(scratch, entries * sizeof(*state_space->ps)); - state_space->wnaf_na = (int *) secp256k1_scratch_alloc(scratch, entries*(WNAF_SIZE(bucket_window+1)) * sizeof(int)); - buckets = (secp256k1_gej *) secp256k1_scratch_alloc(scratch, (1<ps[i].skew_na = 0; - for(j = 0; j < WNAF_SIZE(bucket_window+1); j++) { - state_space->wnaf_na[i * WNAF_SIZE(bucket_window+1) + j] = 0; - } - } - for(i = 0; i < 1< max_alloc) { - break; - } - space_for_points = max_alloc - space_overhead; - - n_points = space_for_points/entry_size; - n_points = n_points > max_points ? max_points : n_points; - if (n_points > res) { - res = n_points; - } - if (n_points < max_points) { - /* A larger bucket_window may support even more points. But if we - * would choose that then the caller couldn't safely use any number - * smaller than what this function returns */ - break; - } - } - return res; -} - -typedef int (*secp256k1_ecmult_multi_func)(const secp256k1_ecmult_context*, secp256k1_scratch*, secp256k1_gej*, const secp256k1_scalar*, secp256k1_ecmult_multi_callback cb, void*, size_t); -static int secp256k1_ecmult_multi_var(const secp256k1_ecmult_context *ctx, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n) { - size_t i; - - int (*f)(const secp256k1_ecmult_context*, secp256k1_scratch*, secp256k1_gej*, const secp256k1_scalar*, secp256k1_ecmult_multi_callback cb, void*, size_t, size_t); - size_t max_points; - size_t n_batches; - size_t n_batch_points; - - secp256k1_gej_set_infinity(r); - if (inp_g_sc == NULL && n == 0) { - return 1; - } else if (n == 0) { - secp256k1_scalar szero; - secp256k1_scalar_set_int(&szero, 0); - secp256k1_ecmult(ctx, r, r, &szero, inp_g_sc); - return 1; - } - - max_points = secp256k1_pippenger_max_points(scratch); - if (max_points == 0) { - return 0; - } else if (max_points > ECMULT_MAX_POINTS_PER_BATCH) { - max_points = ECMULT_MAX_POINTS_PER_BATCH; - } - n_batches = (n+max_points-1)/max_points; - n_batch_points = (n+n_batches-1)/n_batches; - - if (n_batch_points >= ECMULT_PIPPENGER_THRESHOLD) { - f = secp256k1_ecmult_pippenger_batch; - } else { - max_points = secp256k1_strauss_max_points(scratch); - if (max_points == 0) { - return 0; - } - n_batches = (n+max_points-1)/max_points; - n_batch_points = (n+n_batches-1)/n_batches; - f = secp256k1_ecmult_strauss_batch; - } - for(i = 0; i < n_batches; i++) { - size_t nbp = n < n_batch_points ? n : n_batch_points; - size_t offset = n_batch_points*i; - secp256k1_gej tmp; - if (!f(ctx, scratch, &tmp, i == 0 ? inp_g_sc : NULL, cb, cbdata, nbp, offset)) { - return 0; - } - secp256k1_gej_add_var(r, r, &tmp, NULL); - n -= nbp; - } - return 1; -} - -#endif /* SECP256K1_ECMULT_IMPL_H */ diff --git a/Sources/secp256k1/src/field.h b/Sources/secp256k1/src/field.h deleted file mode 100644 index 0e99067..0000000 --- a/Sources/secp256k1/src/field.h +++ /dev/null @@ -1,121 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_FIELD_H -#define SECP256K1_FIELD_H - -/** Field element module. - * - * Field elements can be represented in several ways, but code accessing - * it (and implementations) need to take certain properties into account: - * - Each field element can be normalized or not. - * - Each field element has a magnitude, which represents how far away - * its representation is away from normalization. Normalized elements - * always have a magnitude of 1, but a magnitude of 1 doesn't imply - * normality. - */ - -#include "field_10x26.h" -#include "util.h" - -/** Normalize a field element. */ -static void secp256k1_fe_normalize(secp256k1_fe *r); - -/** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */ -static void secp256k1_fe_normalize_weak(secp256k1_fe *r); - -/** Normalize a field element, without constant-time guarantee. */ -static void secp256k1_fe_normalize_var(secp256k1_fe *r); - -/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field - * implementation may optionally normalize the input, but this should not be relied upon. */ -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r); - -/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field - * implementation may optionally normalize the input, but this should not be relied upon. */ -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r); - -/** Set a field element equal to a small integer. Resulting field element is normalized. */ -static void secp256k1_fe_set_int(secp256k1_fe *r, int a); - -/** Sets a field element equal to zero, initializing all fields. */ -static void secp256k1_fe_clear(secp256k1_fe *a); - -/** Verify whether a field element is zero. Requires the input to be normalized. */ -static int secp256k1_fe_is_zero(const secp256k1_fe *a); - -/** Check the "oddness" of a field element. Requires the input to be normalized. */ -static int secp256k1_fe_is_odd(const secp256k1_fe *a); - -/** Compare two field elements. Requires magnitude-1 inputs. */ -static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b); - -/** Same as secp256k1_fe_equal, but may be variable time. */ -static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b); - -/** Compare two field elements. Requires both inputs to be normalized */ -static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b); - -/** Set a field element equal to 32-byte big endian value. If successful, the resulting field element is normalized. */ -static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a); - -/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ -static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a); - -/** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input - * as an argument. The magnitude of the output is one higher. */ -static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m); - -/** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that - * small integer. */ -static void secp256k1_fe_mul_int(secp256k1_fe *r, int a); - -/** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */ -static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a); - -/** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8. - * The output magnitude is 1 (but not guaranteed to be normalized). */ -static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b); - -/** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8. - * The output magnitude is 1 (but not guaranteed to be normalized). */ -static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a); - -/** If a has a square root, it is computed in r and 1 is returned. If a does not - * have a square root, the root of its negation is computed and 0 is returned. - * The input's magnitude can be at most 8. The output magnitude is 1 (but not - * guaranteed to be normalized). The result in r will always be a square - * itself. */ -static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a); - -/** Checks whether a field element is a quadratic residue. */ -static int secp256k1_fe_is_quad_var(const secp256k1_fe *a); - -/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be - * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ -static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a); - -/** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */ -static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a); - -/** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be - * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and - * outputs must not overlap in memory. */ -static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len); - -/** Convert a field element to the storage type. */ -static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a); - -/** Convert a field element back from the storage type. */ -static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a); - -/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag); - -/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); - -#endif /* SECP256K1_FIELD_H */ diff --git a/Sources/secp256k1/src/field_10x26.h b/Sources/secp256k1/src/field_10x26.h deleted file mode 100644 index 727c526..0000000 --- a/Sources/secp256k1/src/field_10x26.h +++ /dev/null @@ -1,48 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_FIELD_REPR_H -#define SECP256K1_FIELD_REPR_H - -#include - -typedef struct { - /* X = sum(i=0..9, elem[i]*2^26) mod n */ - uint32_t n[10]; -#ifdef VERIFY - int magnitude; - int normalized; -#endif -} secp256k1_fe; - -/* Unpacks a constant into a overlapping multi-limbed FE element. */ -#define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ - (d0) & 0x3FFFFFFUL, \ - (((uint32_t)d0) >> 26) | (((uint32_t)(d1) & 0xFFFFFUL) << 6), \ - (((uint32_t)d1) >> 20) | (((uint32_t)(d2) & 0x3FFFUL) << 12), \ - (((uint32_t)d2) >> 14) | (((uint32_t)(d3) & 0xFFUL) << 18), \ - (((uint32_t)d3) >> 8) | (((uint32_t)(d4) & 0x3UL) << 24), \ - (((uint32_t)d4) >> 2) & 0x3FFFFFFUL, \ - (((uint32_t)d4) >> 28) | (((uint32_t)(d5) & 0x3FFFFFUL) << 4), \ - (((uint32_t)d5) >> 22) | (((uint32_t)(d6) & 0xFFFFUL) << 10), \ - (((uint32_t)d6) >> 16) | (((uint32_t)(d7) & 0x3FFUL) << 16), \ - (((uint32_t)d7) >> 10) \ -} - -#ifdef VERIFY -#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} -#else -#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} -#endif - -typedef struct { - uint32_t n[8]; -} secp256k1_fe_storage; - -#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }} -#define SECP256K1_FE_STORAGE_CONST_GET(d) d.n[7], d.n[6], d.n[5], d.n[4],d.n[3], d.n[2], d.n[1], d.n[0] - -#endif /* SECP256K1_FIELD_REPR_H */ diff --git a/Sources/secp256k1/src/field_10x26_impl.h b/Sources/secp256k1/src/field_10x26_impl.h deleted file mode 100644 index 94f8132..0000000 --- a/Sources/secp256k1/src/field_10x26_impl.h +++ /dev/null @@ -1,1161 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_FIELD_REPR_IMPL_H -#define SECP256K1_FIELD_REPR_IMPL_H - -#include "util.h" -#include "num.h" -#include "field.h" - -#ifdef VERIFY -static void secp256k1_fe_verify(const secp256k1_fe *a) { - const uint32_t *d = a->n; - int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; - r &= (d[0] <= 0x3FFFFFFUL * m); - r &= (d[1] <= 0x3FFFFFFUL * m); - r &= (d[2] <= 0x3FFFFFFUL * m); - r &= (d[3] <= 0x3FFFFFFUL * m); - r &= (d[4] <= 0x3FFFFFFUL * m); - r &= (d[5] <= 0x3FFFFFFUL * m); - r &= (d[6] <= 0x3FFFFFFUL * m); - r &= (d[7] <= 0x3FFFFFFUL * m); - r &= (d[8] <= 0x3FFFFFFUL * m); - r &= (d[9] <= 0x03FFFFFUL * m); - r &= (a->magnitude >= 0); - r &= (a->magnitude <= 32); - if (a->normalized) { - r &= (a->magnitude <= 1); - if (r && (d[9] == 0x03FFFFFUL)) { - uint32_t mid = d[8] & d[7] & d[6] & d[5] & d[4] & d[3] & d[2]; - if (mid == 0x3FFFFFFUL) { - r &= ((d[1] + 0x40UL + ((d[0] + 0x3D1UL) >> 26)) <= 0x3FFFFFFUL); - } - } - } - VERIFY_CHECK(r == 1); -} -#endif - -static void secp256k1_fe_normalize(secp256k1_fe *r) { - uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], - t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; - - /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - uint32_t m; - uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x3D1UL; t1 += (x << 6); - t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8; - - /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t9 >> 23 == 0); - - /* At most a single final reduction is needed; check if the value is >= the field characteristic */ - x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL) - & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); - - /* Apply the final reduction (for constant-time behaviour, we do it always) */ - t0 += x * 0x3D1UL; t1 += (x << 6); - t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; - - /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */ - VERIFY_CHECK(t9 >> 22 == x); - - /* Mask off the possible multiple of 2^256 from the final reduction */ - t9 &= 0x03FFFFFUL; - - r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; - r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; - -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif -} - -static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { - uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], - t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; - - /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x3D1UL; t1 += (x << 6); - t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; - - /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t9 >> 23 == 0); - - r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; - r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; - -#ifdef VERIFY - r->magnitude = 1; - secp256k1_fe_verify(r); -#endif -} - -static void secp256k1_fe_normalize_var(secp256k1_fe *r) { - uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], - t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; - - /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - uint32_t m; - uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x3D1UL; t1 += (x << 6); - t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8; - - /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t9 >> 23 == 0); - - /* At most a single final reduction is needed; check if the value is >= the field characteristic */ - x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL) - & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); - - if (x) { - t0 += 0x3D1UL; t1 += (x << 6); - t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; - - /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */ - VERIFY_CHECK(t9 >> 22 == x); - - /* Mask off the possible multiple of 2^256 from the final reduction */ - t9 &= 0x03FFFFFUL; - } - - r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; - r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; - -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif -} - -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r) { - uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], - t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; - - /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ - uint32_t z0, z1; - - /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x3D1UL; t1 += (x << 6); - t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; z0 = t0; z1 = t0 ^ 0x3D0UL; - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8; - z0 |= t9; z1 &= t9 ^ 0x3C00000UL; - - /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t9 >> 23 == 0); - - return (z0 == 0) | (z1 == 0x3FFFFFFUL); -} - -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r) { - uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; - uint32_t z0, z1; - uint32_t x; - - t0 = r->n[0]; - t9 = r->n[9]; - - /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - x = t9 >> 22; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x3D1UL; - - /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ - z0 = t0 & 0x3FFFFFFUL; - z1 = z0 ^ 0x3D0UL; - - /* Fast return path should catch the majority of cases */ - if ((z0 != 0UL) & (z1 != 0x3FFFFFFUL)) { - return 0; - } - - t1 = r->n[1]; - t2 = r->n[2]; - t3 = r->n[3]; - t4 = r->n[4]; - t5 = r->n[5]; - t6 = r->n[6]; - t7 = r->n[7]; - t8 = r->n[8]; - - t9 &= 0x03FFFFFUL; - t1 += (x << 6); - - t1 += (t0 >> 26); - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8; - z0 |= t9; z1 &= t9 ^ 0x3C00000UL; - - /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t9 >> 23 == 0); - - return (z0 == 0) | (z1 == 0x3FFFFFFUL); -} - -SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) { - r->n[0] = a; - r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif -} - -SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { - const uint32_t *t = a->n; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif - return (t[0] | t[1] | t[2] | t[3] | t[4] | t[5] | t[6] | t[7] | t[8] | t[9]) == 0; -} - -SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif - return a->n[0] & 1; -} - -SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { - int i; -#ifdef VERIFY - a->magnitude = 0; - a->normalized = 1; -#endif - for (i=0; i<10; i++) { - a->n[i] = 0; - } -} - -static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { - int i; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - VERIFY_CHECK(b->normalized); - secp256k1_fe_verify(a); - secp256k1_fe_verify(b); -#endif - for (i = 9; i >= 0; i--) { - if (a->n[i] > b->n[i]) { - return 1; - } - if (a->n[i] < b->n[i]) { - return -1; - } - } - return 0; -} - -static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) { - r->n[0] = (uint32_t)a[31] | ((uint32_t)a[30] << 8) | ((uint32_t)a[29] << 16) | ((uint32_t)(a[28] & 0x3) << 24); - r->n[1] = (uint32_t)((a[28] >> 2) & 0x3f) | ((uint32_t)a[27] << 6) | ((uint32_t)a[26] << 14) | ((uint32_t)(a[25] & 0xf) << 22); - r->n[2] = (uint32_t)((a[25] >> 4) & 0xf) | ((uint32_t)a[24] << 4) | ((uint32_t)a[23] << 12) | ((uint32_t)(a[22] & 0x3f) << 20); - r->n[3] = (uint32_t)((a[22] >> 6) & 0x3) | ((uint32_t)a[21] << 2) | ((uint32_t)a[20] << 10) | ((uint32_t)a[19] << 18); - r->n[4] = (uint32_t)a[18] | ((uint32_t)a[17] << 8) | ((uint32_t)a[16] << 16) | ((uint32_t)(a[15] & 0x3) << 24); - r->n[5] = (uint32_t)((a[15] >> 2) & 0x3f) | ((uint32_t)a[14] << 6) | ((uint32_t)a[13] << 14) | ((uint32_t)(a[12] & 0xf) << 22); - r->n[6] = (uint32_t)((a[12] >> 4) & 0xf) | ((uint32_t)a[11] << 4) | ((uint32_t)a[10] << 12) | ((uint32_t)(a[9] & 0x3f) << 20); - r->n[7] = (uint32_t)((a[9] >> 6) & 0x3) | ((uint32_t)a[8] << 2) | ((uint32_t)a[7] << 10) | ((uint32_t)a[6] << 18); - r->n[8] = (uint32_t)a[5] | ((uint32_t)a[4] << 8) | ((uint32_t)a[3] << 16) | ((uint32_t)(a[2] & 0x3) << 24); - r->n[9] = (uint32_t)((a[2] >> 2) & 0x3f) | ((uint32_t)a[1] << 6) | ((uint32_t)a[0] << 14); - - if (r->n[9] == 0x3FFFFFUL && (r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL && (r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL) { - return 0; - } -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif - return 1; -} - -/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ -static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif - r[0] = (a->n[9] >> 14) & 0xff; - r[1] = (a->n[9] >> 6) & 0xff; - r[2] = ((a->n[9] & 0x3F) << 2) | ((a->n[8] >> 24) & 0x3); - r[3] = (a->n[8] >> 16) & 0xff; - r[4] = (a->n[8] >> 8) & 0xff; - r[5] = a->n[8] & 0xff; - r[6] = (a->n[7] >> 18) & 0xff; - r[7] = (a->n[7] >> 10) & 0xff; - r[8] = (a->n[7] >> 2) & 0xff; - r[9] = ((a->n[7] & 0x3) << 6) | ((a->n[6] >> 20) & 0x3f); - r[10] = (a->n[6] >> 12) & 0xff; - r[11] = (a->n[6] >> 4) & 0xff; - r[12] = ((a->n[6] & 0xf) << 4) | ((a->n[5] >> 22) & 0xf); - r[13] = (a->n[5] >> 14) & 0xff; - r[14] = (a->n[5] >> 6) & 0xff; - r[15] = ((a->n[5] & 0x3f) << 2) | ((a->n[4] >> 24) & 0x3); - r[16] = (a->n[4] >> 16) & 0xff; - r[17] = (a->n[4] >> 8) & 0xff; - r[18] = a->n[4] & 0xff; - r[19] = (a->n[3] >> 18) & 0xff; - r[20] = (a->n[3] >> 10) & 0xff; - r[21] = (a->n[3] >> 2) & 0xff; - r[22] = ((a->n[3] & 0x3) << 6) | ((a->n[2] >> 20) & 0x3f); - r[23] = (a->n[2] >> 12) & 0xff; - r[24] = (a->n[2] >> 4) & 0xff; - r[25] = ((a->n[2] & 0xf) << 4) | ((a->n[1] >> 22) & 0xf); - r[26] = (a->n[1] >> 14) & 0xff; - r[27] = (a->n[1] >> 6) & 0xff; - r[28] = ((a->n[1] & 0x3f) << 2) | ((a->n[0] >> 24) & 0x3); - r[29] = (a->n[0] >> 16) & 0xff; - r[30] = (a->n[0] >> 8) & 0xff; - r[31] = a->n[0] & 0xff; -} - -SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= m); - secp256k1_fe_verify(a); -#endif - r->n[0] = 0x3FFFC2FUL * 2 * (m + 1) - a->n[0]; - r->n[1] = 0x3FFFFBFUL * 2 * (m + 1) - a->n[1]; - r->n[2] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[2]; - r->n[3] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[3]; - r->n[4] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[4]; - r->n[5] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[5]; - r->n[6] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[6]; - r->n[7] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[7]; - r->n[8] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[8]; - r->n[9] = 0x03FFFFFUL * 2 * (m + 1) - a->n[9]; -#ifdef VERIFY - r->magnitude = m + 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { - r->n[0] *= a; - r->n[1] *= a; - r->n[2] *= a; - r->n[3] *= a; - r->n[4] *= a; - r->n[5] *= a; - r->n[6] *= a; - r->n[7] *= a; - r->n[8] *= a; - r->n[9] *= a; -#ifdef VERIFY - r->magnitude *= a; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { -#ifdef VERIFY - secp256k1_fe_verify(a); -#endif - r->n[0] += a->n[0]; - r->n[1] += a->n[1]; - r->n[2] += a->n[2]; - r->n[3] += a->n[3]; - r->n[4] += a->n[4]; - r->n[5] += a->n[5]; - r->n[6] += a->n[6]; - r->n[7] += a->n[7]; - r->n[8] += a->n[8]; - r->n[9] += a->n[9]; -#ifdef VERIFY - r->magnitude += a->magnitude; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -#if defined(USE_EXTERNAL_ASM) - -/* External assembler implementation */ -void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b); -void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a); - -#else - -#ifdef VERIFY -#define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) -#else -#define VERIFY_BITS(x, n) do { } while(0) -#endif - -SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b) { - uint64_t c, d; - uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8; - uint32_t t9, t1, t0, t2, t3, t4, t5, t6, t7; - const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; - - VERIFY_BITS(a[0], 30); - VERIFY_BITS(a[1], 30); - VERIFY_BITS(a[2], 30); - VERIFY_BITS(a[3], 30); - VERIFY_BITS(a[4], 30); - VERIFY_BITS(a[5], 30); - VERIFY_BITS(a[6], 30); - VERIFY_BITS(a[7], 30); - VERIFY_BITS(a[8], 30); - VERIFY_BITS(a[9], 26); - VERIFY_BITS(b[0], 30); - VERIFY_BITS(b[1], 30); - VERIFY_BITS(b[2], 30); - VERIFY_BITS(b[3], 30); - VERIFY_BITS(b[4], 30); - VERIFY_BITS(b[5], 30); - VERIFY_BITS(b[6], 30); - VERIFY_BITS(b[7], 30); - VERIFY_BITS(b[8], 30); - VERIFY_BITS(b[9], 26); - - /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. - * px is a shorthand for sum(a[i]*b[x-i], i=0..x). - * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. - */ - - d = (uint64_t)a[0] * b[9] - + (uint64_t)a[1] * b[8] - + (uint64_t)a[2] * b[7] - + (uint64_t)a[3] * b[6] - + (uint64_t)a[4] * b[5] - + (uint64_t)a[5] * b[4] - + (uint64_t)a[6] * b[3] - + (uint64_t)a[7] * b[2] - + (uint64_t)a[8] * b[1] - + (uint64_t)a[9] * b[0]; - /* VERIFY_BITS(d, 64); */ - /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ - t9 = d & M; d >>= 26; - VERIFY_BITS(t9, 26); - VERIFY_BITS(d, 38); - /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ - - c = (uint64_t)a[0] * b[0]; - VERIFY_BITS(c, 60); - /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */ - d += (uint64_t)a[1] * b[9] - + (uint64_t)a[2] * b[8] - + (uint64_t)a[3] * b[7] - + (uint64_t)a[4] * b[6] - + (uint64_t)a[5] * b[5] - + (uint64_t)a[6] * b[4] - + (uint64_t)a[7] * b[3] - + (uint64_t)a[8] * b[2] - + (uint64_t)a[9] * b[1]; - VERIFY_BITS(d, 63); - /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - u0 = d & M; d >>= 26; c += u0 * R0; - VERIFY_BITS(u0, 26); - VERIFY_BITS(d, 37); - VERIFY_BITS(c, 61); - /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - t0 = c & M; c >>= 26; c += u0 * R1; - VERIFY_BITS(t0, 26); - VERIFY_BITS(c, 37); - /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - - c += (uint64_t)a[0] * b[1] - + (uint64_t)a[1] * b[0]; - VERIFY_BITS(c, 62); - /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */ - d += (uint64_t)a[2] * b[9] - + (uint64_t)a[3] * b[8] - + (uint64_t)a[4] * b[7] - + (uint64_t)a[5] * b[6] - + (uint64_t)a[6] * b[5] - + (uint64_t)a[7] * b[4] - + (uint64_t)a[8] * b[3] - + (uint64_t)a[9] * b[2]; - VERIFY_BITS(d, 63); - /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - u1 = d & M; d >>= 26; c += u1 * R0; - VERIFY_BITS(u1, 26); - VERIFY_BITS(d, 37); - VERIFY_BITS(c, 63); - /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - t1 = c & M; c >>= 26; c += u1 * R1; - VERIFY_BITS(t1, 26); - VERIFY_BITS(c, 38); - /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - - c += (uint64_t)a[0] * b[2] - + (uint64_t)a[1] * b[1] - + (uint64_t)a[2] * b[0]; - VERIFY_BITS(c, 62); - /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - d += (uint64_t)a[3] * b[9] - + (uint64_t)a[4] * b[8] - + (uint64_t)a[5] * b[7] - + (uint64_t)a[6] * b[6] - + (uint64_t)a[7] * b[5] - + (uint64_t)a[8] * b[4] - + (uint64_t)a[9] * b[3]; - VERIFY_BITS(d, 63); - /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - u2 = d & M; d >>= 26; c += u2 * R0; - VERIFY_BITS(u2, 26); - VERIFY_BITS(d, 37); - VERIFY_BITS(c, 63); - /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - t2 = c & M; c >>= 26; c += u2 * R1; - VERIFY_BITS(t2, 26); - VERIFY_BITS(c, 38); - /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - - c += (uint64_t)a[0] * b[3] - + (uint64_t)a[1] * b[2] - + (uint64_t)a[2] * b[1] - + (uint64_t)a[3] * b[0]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - d += (uint64_t)a[4] * b[9] - + (uint64_t)a[5] * b[8] - + (uint64_t)a[6] * b[7] - + (uint64_t)a[7] * b[6] - + (uint64_t)a[8] * b[5] - + (uint64_t)a[9] * b[4]; - VERIFY_BITS(d, 63); - /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - u3 = d & M; d >>= 26; c += u3 * R0; - VERIFY_BITS(u3, 26); - VERIFY_BITS(d, 37); - /* VERIFY_BITS(c, 64); */ - /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - t3 = c & M; c >>= 26; c += u3 * R1; - VERIFY_BITS(t3, 26); - VERIFY_BITS(c, 39); - /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - - c += (uint64_t)a[0] * b[4] - + (uint64_t)a[1] * b[3] - + (uint64_t)a[2] * b[2] - + (uint64_t)a[3] * b[1] - + (uint64_t)a[4] * b[0]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - d += (uint64_t)a[5] * b[9] - + (uint64_t)a[6] * b[8] - + (uint64_t)a[7] * b[7] - + (uint64_t)a[8] * b[6] - + (uint64_t)a[9] * b[5]; - VERIFY_BITS(d, 62); - /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - u4 = d & M; d >>= 26; c += u4 * R0; - VERIFY_BITS(u4, 26); - VERIFY_BITS(d, 36); - /* VERIFY_BITS(c, 64); */ - /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - t4 = c & M; c >>= 26; c += u4 * R1; - VERIFY_BITS(t4, 26); - VERIFY_BITS(c, 39); - /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - - c += (uint64_t)a[0] * b[5] - + (uint64_t)a[1] * b[4] - + (uint64_t)a[2] * b[3] - + (uint64_t)a[3] * b[2] - + (uint64_t)a[4] * b[1] - + (uint64_t)a[5] * b[0]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)a[6] * b[9] - + (uint64_t)a[7] * b[8] - + (uint64_t)a[8] * b[7] - + (uint64_t)a[9] * b[6]; - VERIFY_BITS(d, 62); - /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - u5 = d & M; d >>= 26; c += u5 * R0; - VERIFY_BITS(u5, 26); - VERIFY_BITS(d, 36); - /* VERIFY_BITS(c, 64); */ - /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - t5 = c & M; c >>= 26; c += u5 * R1; - VERIFY_BITS(t5, 26); - VERIFY_BITS(c, 39); - /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - - c += (uint64_t)a[0] * b[6] - + (uint64_t)a[1] * b[5] - + (uint64_t)a[2] * b[4] - + (uint64_t)a[3] * b[3] - + (uint64_t)a[4] * b[2] - + (uint64_t)a[5] * b[1] - + (uint64_t)a[6] * b[0]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)a[7] * b[9] - + (uint64_t)a[8] * b[8] - + (uint64_t)a[9] * b[7]; - VERIFY_BITS(d, 61); - /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - u6 = d & M; d >>= 26; c += u6 * R0; - VERIFY_BITS(u6, 26); - VERIFY_BITS(d, 35); - /* VERIFY_BITS(c, 64); */ - /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - t6 = c & M; c >>= 26; c += u6 * R1; - VERIFY_BITS(t6, 26); - VERIFY_BITS(c, 39); - /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - - c += (uint64_t)a[0] * b[7] - + (uint64_t)a[1] * b[6] - + (uint64_t)a[2] * b[5] - + (uint64_t)a[3] * b[4] - + (uint64_t)a[4] * b[3] - + (uint64_t)a[5] * b[2] - + (uint64_t)a[6] * b[1] - + (uint64_t)a[7] * b[0]; - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x8000007C00000007ULL); - /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)a[8] * b[9] - + (uint64_t)a[9] * b[8]; - VERIFY_BITS(d, 58); - /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - u7 = d & M; d >>= 26; c += u7 * R0; - VERIFY_BITS(u7, 26); - VERIFY_BITS(d, 32); - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL); - /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - t7 = c & M; c >>= 26; c += u7 * R1; - VERIFY_BITS(t7, 26); - VERIFY_BITS(c, 38); - /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - - c += (uint64_t)a[0] * b[8] - + (uint64_t)a[1] * b[7] - + (uint64_t)a[2] * b[6] - + (uint64_t)a[3] * b[5] - + (uint64_t)a[4] * b[4] - + (uint64_t)a[5] * b[3] - + (uint64_t)a[6] * b[2] - + (uint64_t)a[7] * b[1] - + (uint64_t)a[8] * b[0]; - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x9000007B80000008ULL); - /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)a[9] * b[9]; - VERIFY_BITS(d, 57); - /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - u8 = d & M; d >>= 26; c += u8 * R0; - VERIFY_BITS(u8, 26); - VERIFY_BITS(d, 31); - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - r[3] = t3; - VERIFY_BITS(r[3], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[4] = t4; - VERIFY_BITS(r[4], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[5] = t5; - VERIFY_BITS(r[5], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[6] = t6; - VERIFY_BITS(r[6], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[7] = t7; - VERIFY_BITS(r[7], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - r[8] = c & M; c >>= 26; c += u8 * R1; - VERIFY_BITS(r[8], 26); - VERIFY_BITS(c, 39); - /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R0 + t9; - VERIFY_BITS(c, 45); - /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4); - VERIFY_BITS(r[9], 22); - VERIFY_BITS(c, 46); - /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - d = c * (R0 >> 4) + t0; - VERIFY_BITS(d, 56); - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[0] = d & M; d >>= 26; - VERIFY_BITS(r[0], 26); - VERIFY_BITS(d, 30); - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += c * (R1 >> 4) + t1; - VERIFY_BITS(d, 53); - VERIFY_CHECK(d <= 0x10000003FFFFBFULL); - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[1] = d & M; d >>= 26; - VERIFY_BITS(r[1], 26); - VERIFY_BITS(d, 27); - VERIFY_CHECK(d <= 0x4000000ULL); - /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += t2; - VERIFY_BITS(d, 27); - /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[2] = d; - VERIFY_BITS(r[2], 27); - /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ -} - -SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a) { - uint64_t c, d; - uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8; - uint32_t t9, t0, t1, t2, t3, t4, t5, t6, t7; - const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; - - VERIFY_BITS(a[0], 30); - VERIFY_BITS(a[1], 30); - VERIFY_BITS(a[2], 30); - VERIFY_BITS(a[3], 30); - VERIFY_BITS(a[4], 30); - VERIFY_BITS(a[5], 30); - VERIFY_BITS(a[6], 30); - VERIFY_BITS(a[7], 30); - VERIFY_BITS(a[8], 30); - VERIFY_BITS(a[9], 26); - - /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. - * px is a shorthand for sum(a[i]*a[x-i], i=0..x). - * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. - */ - - d = (uint64_t)(a[0]*2) * a[9] - + (uint64_t)(a[1]*2) * a[8] - + (uint64_t)(a[2]*2) * a[7] - + (uint64_t)(a[3]*2) * a[6] - + (uint64_t)(a[4]*2) * a[5]; - /* VERIFY_BITS(d, 64); */ - /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ - t9 = d & M; d >>= 26; - VERIFY_BITS(t9, 26); - VERIFY_BITS(d, 38); - /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ - - c = (uint64_t)a[0] * a[0]; - VERIFY_BITS(c, 60); - /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */ - d += (uint64_t)(a[1]*2) * a[9] - + (uint64_t)(a[2]*2) * a[8] - + (uint64_t)(a[3]*2) * a[7] - + (uint64_t)(a[4]*2) * a[6] - + (uint64_t)a[5] * a[5]; - VERIFY_BITS(d, 63); - /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - u0 = d & M; d >>= 26; c += u0 * R0; - VERIFY_BITS(u0, 26); - VERIFY_BITS(d, 37); - VERIFY_BITS(c, 61); - /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - t0 = c & M; c >>= 26; c += u0 * R1; - VERIFY_BITS(t0, 26); - VERIFY_BITS(c, 37); - /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - - c += (uint64_t)(a[0]*2) * a[1]; - VERIFY_BITS(c, 62); - /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */ - d += (uint64_t)(a[2]*2) * a[9] - + (uint64_t)(a[3]*2) * a[8] - + (uint64_t)(a[4]*2) * a[7] - + (uint64_t)(a[5]*2) * a[6]; - VERIFY_BITS(d, 63); - /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - u1 = d & M; d >>= 26; c += u1 * R0; - VERIFY_BITS(u1, 26); - VERIFY_BITS(d, 37); - VERIFY_BITS(c, 63); - /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - t1 = c & M; c >>= 26; c += u1 * R1; - VERIFY_BITS(t1, 26); - VERIFY_BITS(c, 38); - /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[2] - + (uint64_t)a[1] * a[1]; - VERIFY_BITS(c, 62); - /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - d += (uint64_t)(a[3]*2) * a[9] - + (uint64_t)(a[4]*2) * a[8] - + (uint64_t)(a[5]*2) * a[7] - + (uint64_t)a[6] * a[6]; - VERIFY_BITS(d, 63); - /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - u2 = d & M; d >>= 26; c += u2 * R0; - VERIFY_BITS(u2, 26); - VERIFY_BITS(d, 37); - VERIFY_BITS(c, 63); - /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - t2 = c & M; c >>= 26; c += u2 * R1; - VERIFY_BITS(t2, 26); - VERIFY_BITS(c, 38); - /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[3] - + (uint64_t)(a[1]*2) * a[2]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - d += (uint64_t)(a[4]*2) * a[9] - + (uint64_t)(a[5]*2) * a[8] - + (uint64_t)(a[6]*2) * a[7]; - VERIFY_BITS(d, 63); - /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - u3 = d & M; d >>= 26; c += u3 * R0; - VERIFY_BITS(u3, 26); - VERIFY_BITS(d, 37); - /* VERIFY_BITS(c, 64); */ - /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - t3 = c & M; c >>= 26; c += u3 * R1; - VERIFY_BITS(t3, 26); - VERIFY_BITS(c, 39); - /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[4] - + (uint64_t)(a[1]*2) * a[3] - + (uint64_t)a[2] * a[2]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - d += (uint64_t)(a[5]*2) * a[9] - + (uint64_t)(a[6]*2) * a[8] - + (uint64_t)a[7] * a[7]; - VERIFY_BITS(d, 62); - /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - u4 = d & M; d >>= 26; c += u4 * R0; - VERIFY_BITS(u4, 26); - VERIFY_BITS(d, 36); - /* VERIFY_BITS(c, 64); */ - /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - t4 = c & M; c >>= 26; c += u4 * R1; - VERIFY_BITS(t4, 26); - VERIFY_BITS(c, 39); - /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[5] - + (uint64_t)(a[1]*2) * a[4] - + (uint64_t)(a[2]*2) * a[3]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)(a[6]*2) * a[9] - + (uint64_t)(a[7]*2) * a[8]; - VERIFY_BITS(d, 62); - /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - u5 = d & M; d >>= 26; c += u5 * R0; - VERIFY_BITS(u5, 26); - VERIFY_BITS(d, 36); - /* VERIFY_BITS(c, 64); */ - /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - t5 = c & M; c >>= 26; c += u5 * R1; - VERIFY_BITS(t5, 26); - VERIFY_BITS(c, 39); - /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[6] - + (uint64_t)(a[1]*2) * a[5] - + (uint64_t)(a[2]*2) * a[4] - + (uint64_t)a[3] * a[3]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)(a[7]*2) * a[9] - + (uint64_t)a[8] * a[8]; - VERIFY_BITS(d, 61); - /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - u6 = d & M; d >>= 26; c += u6 * R0; - VERIFY_BITS(u6, 26); - VERIFY_BITS(d, 35); - /* VERIFY_BITS(c, 64); */ - /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - t6 = c & M; c >>= 26; c += u6 * R1; - VERIFY_BITS(t6, 26); - VERIFY_BITS(c, 39); - /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[7] - + (uint64_t)(a[1]*2) * a[6] - + (uint64_t)(a[2]*2) * a[5] - + (uint64_t)(a[3]*2) * a[4]; - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x8000007C00000007ULL); - /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)(a[8]*2) * a[9]; - VERIFY_BITS(d, 58); - /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - u7 = d & M; d >>= 26; c += u7 * R0; - VERIFY_BITS(u7, 26); - VERIFY_BITS(d, 32); - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL); - /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - t7 = c & M; c >>= 26; c += u7 * R1; - VERIFY_BITS(t7, 26); - VERIFY_BITS(c, 38); - /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[8] - + (uint64_t)(a[1]*2) * a[7] - + (uint64_t)(a[2]*2) * a[6] - + (uint64_t)(a[3]*2) * a[5] - + (uint64_t)a[4] * a[4]; - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x9000007B80000008ULL); - /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)a[9] * a[9]; - VERIFY_BITS(d, 57); - /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - u8 = d & M; d >>= 26; c += u8 * R0; - VERIFY_BITS(u8, 26); - VERIFY_BITS(d, 31); - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - r[3] = t3; - VERIFY_BITS(r[3], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[4] = t4; - VERIFY_BITS(r[4], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[5] = t5; - VERIFY_BITS(r[5], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[6] = t6; - VERIFY_BITS(r[6], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[7] = t7; - VERIFY_BITS(r[7], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - r[8] = c & M; c >>= 26; c += u8 * R1; - VERIFY_BITS(r[8], 26); - VERIFY_BITS(c, 39); - /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R0 + t9; - VERIFY_BITS(c, 45); - /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4); - VERIFY_BITS(r[9], 22); - VERIFY_BITS(c, 46); - /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - d = c * (R0 >> 4) + t0; - VERIFY_BITS(d, 56); - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[0] = d & M; d >>= 26; - VERIFY_BITS(r[0], 26); - VERIFY_BITS(d, 30); - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += c * (R1 >> 4) + t1; - VERIFY_BITS(d, 53); - VERIFY_CHECK(d <= 0x10000003FFFFBFULL); - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[1] = d & M; d >>= 26; - VERIFY_BITS(r[1], 26); - VERIFY_BITS(d, 27); - VERIFY_CHECK(d <= 0x4000000ULL); - /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += t2; - VERIFY_BITS(d, 27); - /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[2] = d; - VERIFY_BITS(r[2], 27); - /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ -} -#endif - -static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= 8); - VERIFY_CHECK(b->magnitude <= 8); - secp256k1_fe_verify(a); - secp256k1_fe_verify(b); - VERIFY_CHECK(r != b); -#endif - secp256k1_fe_mul_inner(r->n, a->n, b->n); -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= 8); - secp256k1_fe_verify(a); -#endif - secp256k1_fe_sqr_inner(r->n, a->n); -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { - uint32_t mask0, mask1; - mask0 = flag + ~((uint32_t)0); - mask1 = ~mask0; - r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); - r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); - r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); - r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); - r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); - r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1); - r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1); - r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); - r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1); - r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1); -#ifdef VERIFY - if (a->magnitude > r->magnitude) { - r->magnitude = a->magnitude; - } - r->normalized &= a->normalized; -#endif -} - -static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { - uint32_t mask0, mask1; - mask0 = flag + ~((uint32_t)0); - mask1 = ~mask0; - r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); - r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); - r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); - r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); - r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); - r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1); - r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1); - r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); -} - -static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); -#endif - r->n[0] = a->n[0] | a->n[1] << 26; - r->n[1] = a->n[1] >> 6 | a->n[2] << 20; - r->n[2] = a->n[2] >> 12 | a->n[3] << 14; - r->n[3] = a->n[3] >> 18 | a->n[4] << 8; - r->n[4] = a->n[4] >> 24 | a->n[5] << 2 | a->n[6] << 28; - r->n[5] = a->n[6] >> 4 | a->n[7] << 22; - r->n[6] = a->n[7] >> 10 | a->n[8] << 16; - r->n[7] = a->n[8] >> 16 | a->n[9] << 10; -} - -static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { - r->n[0] = a->n[0] & 0x3FFFFFFUL; - r->n[1] = a->n[0] >> 26 | ((a->n[1] << 6) & 0x3FFFFFFUL); - r->n[2] = a->n[1] >> 20 | ((a->n[2] << 12) & 0x3FFFFFFUL); - r->n[3] = a->n[2] >> 14 | ((a->n[3] << 18) & 0x3FFFFFFUL); - r->n[4] = a->n[3] >> 8 | ((a->n[4] << 24) & 0x3FFFFFFUL); - r->n[5] = (a->n[4] >> 2) & 0x3FFFFFFUL; - r->n[6] = a->n[4] >> 28 | ((a->n[5] << 4) & 0x3FFFFFFUL); - r->n[7] = a->n[5] >> 22 | ((a->n[6] << 10) & 0x3FFFFFFUL); - r->n[8] = a->n[6] >> 16 | ((a->n[7] << 16) & 0x3FFFFFFUL); - r->n[9] = a->n[7] >> 10; -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; -#endif -} - -#endif /* SECP256K1_FIELD_REPR_IMPL_H */ diff --git a/Sources/secp256k1/src/field_impl.h b/Sources/secp256k1/src/field_impl.h deleted file mode 100644 index b4b2275..0000000 --- a/Sources/secp256k1/src/field_impl.h +++ /dev/null @@ -1,306 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_FIELD_IMPL_H -#define SECP256K1_FIELD_IMPL_H - -#define USE_FIELD_INV_BUILTIN - -#include "util.h" -#include "field_10x26_impl.h" - -SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { - secp256k1_fe na; - secp256k1_fe_negate(&na, a, 1); - secp256k1_fe_add(&na, b); - return secp256k1_fe_normalizes_to_zero(&na); -} - -SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b) { - secp256k1_fe na; - secp256k1_fe_negate(&na, a, 1); - secp256k1_fe_add(&na, b); - return secp256k1_fe_normalizes_to_zero_var(&na); -} - -static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) { - /** Given that p is congruent to 3 mod 4, we can compute the square root of - * a mod p as the (p+1)/4'th power of a. - * - * As (p+1)/4 is an even number, it will have the same result for a and for - * (-a). Only one of these two numbers actually has a square root however, - * so we test at the end by squaring and comparing to the input. - * Also because (p+1)/4 is an even number, the computed square root is - * itself always a square (a ** ((p+1)/4) is the square of a ** ((p+1)/8)). - */ - secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; - int j; - - /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in - * { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: - * 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] - */ - - secp256k1_fe_sqr(&x2, a); - secp256k1_fe_mul(&x2, &x2, a); - - secp256k1_fe_sqr(&x3, &x2); - secp256k1_fe_mul(&x3, &x3, a); - - x6 = x3; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x6, &x6); - } - secp256k1_fe_mul(&x6, &x6, &x3); - - x9 = x6; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x9, &x9); - } - secp256k1_fe_mul(&x9, &x9, &x3); - - x11 = x9; - for (j=0; j<2; j++) { - secp256k1_fe_sqr(&x11, &x11); - } - secp256k1_fe_mul(&x11, &x11, &x2); - - x22 = x11; - for (j=0; j<11; j++) { - secp256k1_fe_sqr(&x22, &x22); - } - secp256k1_fe_mul(&x22, &x22, &x11); - - x44 = x22; - for (j=0; j<22; j++) { - secp256k1_fe_sqr(&x44, &x44); - } - secp256k1_fe_mul(&x44, &x44, &x22); - - x88 = x44; - for (j=0; j<44; j++) { - secp256k1_fe_sqr(&x88, &x88); - } - secp256k1_fe_mul(&x88, &x88, &x44); - - x176 = x88; - for (j=0; j<88; j++) { - secp256k1_fe_sqr(&x176, &x176); - } - secp256k1_fe_mul(&x176, &x176, &x88); - - x220 = x176; - for (j=0; j<44; j++) { - secp256k1_fe_sqr(&x220, &x220); - } - secp256k1_fe_mul(&x220, &x220, &x44); - - x223 = x220; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x223, &x223); - } - secp256k1_fe_mul(&x223, &x223, &x3); - - /* The final result is then assembled using a sliding window over the blocks. */ - - t1 = x223; - for (j=0; j<23; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, &x22); - for (j=0; j<6; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, &x2); - secp256k1_fe_sqr(&t1, &t1); - secp256k1_fe_sqr(r, &t1); - - /* Check that a square root was actually calculated */ - - secp256k1_fe_sqr(&t1, r); - return secp256k1_fe_equal(&t1, a); -} - -static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a) { - secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; - int j; - - /** The binary representation of (p - 2) has 5 blocks of 1s, with lengths in - * { 1, 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: - * [1], [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] - */ - - secp256k1_fe_sqr(&x2, a); - secp256k1_fe_mul(&x2, &x2, a); - - secp256k1_fe_sqr(&x3, &x2); - secp256k1_fe_mul(&x3, &x3, a); - - x6 = x3; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x6, &x6); - } - secp256k1_fe_mul(&x6, &x6, &x3); - - x9 = x6; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x9, &x9); - } - secp256k1_fe_mul(&x9, &x9, &x3); - - x11 = x9; - for (j=0; j<2; j++) { - secp256k1_fe_sqr(&x11, &x11); - } - secp256k1_fe_mul(&x11, &x11, &x2); - - x22 = x11; - for (j=0; j<11; j++) { - secp256k1_fe_sqr(&x22, &x22); - } - secp256k1_fe_mul(&x22, &x22, &x11); - - x44 = x22; - for (j=0; j<22; j++) { - secp256k1_fe_sqr(&x44, &x44); - } - secp256k1_fe_mul(&x44, &x44, &x22); - - x88 = x44; - for (j=0; j<44; j++) { - secp256k1_fe_sqr(&x88, &x88); - } - secp256k1_fe_mul(&x88, &x88, &x44); - - x176 = x88; - for (j=0; j<88; j++) { - secp256k1_fe_sqr(&x176, &x176); - } - secp256k1_fe_mul(&x176, &x176, &x88); - - x220 = x176; - for (j=0; j<44; j++) { - secp256k1_fe_sqr(&x220, &x220); - } - secp256k1_fe_mul(&x220, &x220, &x44); - - x223 = x220; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x223, &x223); - } - secp256k1_fe_mul(&x223, &x223, &x3); - - /* The final result is then assembled using a sliding window over the blocks. */ - - t1 = x223; - for (j=0; j<23; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, &x22); - for (j=0; j<5; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, a); - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, &x2); - for (j=0; j<2; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(r, a, &t1); -} - -static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a) { -#if defined(USE_FIELD_INV_BUILTIN) - secp256k1_fe_inv(r, a); -#elif defined(USE_FIELD_INV_NUM) - secp256k1_num n, m; - static const secp256k1_fe negone = SECP256K1_FE_CONST( - 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, - 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 0xFFFFFC2EUL - ); - /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ - static const unsigned char prime[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F - }; - unsigned char b[32]; - int res; - secp256k1_fe c = *a; - secp256k1_fe_normalize_var(&c); - secp256k1_fe_get_b32(b, &c); - secp256k1_num_set_bin(&n, b, 32); - secp256k1_num_set_bin(&m, prime, 32); - secp256k1_num_mod_inverse(&n, &n, &m); - secp256k1_num_get_bin(b, 32, &n); - res = secp256k1_fe_set_b32(r, b); - (void)res; - VERIFY_CHECK(res); - /* Verify the result is the (unique) valid inverse using non-GMP code. */ - secp256k1_fe_mul(&c, &c, r); - secp256k1_fe_add(&c, &negone); - CHECK(secp256k1_fe_normalizes_to_zero_var(&c)); -#else -#error "Please select field inverse implementation" -#endif -} - -static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len) { - secp256k1_fe u; - size_t i; - if (len < 1) { - return; - } - - VERIFY_CHECK((r + len <= a) || (a + len <= r)); - - r[0] = a[0]; - - i = 0; - while (++i < len) { - secp256k1_fe_mul(&r[i], &r[i - 1], &a[i]); - } - - secp256k1_fe_inv_var(&u, &r[--i]); - - while (i > 0) { - size_t j = i--; - secp256k1_fe_mul(&r[j], &r[i], &u); - secp256k1_fe_mul(&u, &u, &a[j]); - } - - r[0] = u; -} - -static int secp256k1_fe_is_quad_var(const secp256k1_fe *a) { -#ifndef USE_NUM_NONE - unsigned char b[32]; - secp256k1_num n; - secp256k1_num m; - /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ - static const unsigned char prime[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F - }; - - secp256k1_fe c = *a; - secp256k1_fe_normalize_var(&c); - secp256k1_fe_get_b32(b, &c); - secp256k1_num_set_bin(&n, b, 32); - secp256k1_num_set_bin(&m, prime, 32); - return secp256k1_num_jacobi(&n, &m) >= 0; -#else - secp256k1_fe r; - return secp256k1_fe_sqrt(&r, a); -#endif -} - -#endif /* SECP256K1_FIELD_IMPL_H */ diff --git a/Sources/secp256k1/src/group.h b/Sources/secp256k1/src/group.h deleted file mode 100644 index 3947ea2..0000000 --- a/Sources/secp256k1/src/group.h +++ /dev/null @@ -1,147 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_GROUP_H -#define SECP256K1_GROUP_H - -#include "num.h" -#include "field.h" - -/** A group element of the secp256k1 curve, in affine coordinates. */ -typedef struct { - secp256k1_fe x; - secp256k1_fe y; - int infinity; /* whether this represents the point at infinity */ -} secp256k1_ge; - -#define SECP256K1_GE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), 0} -#define SECP256K1_GE_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} - -/** A group element of the secp256k1 curve, in jacobian coordinates. */ -typedef struct { - secp256k1_fe x; /* actual X: x/z^2 */ - secp256k1_fe y; /* actual Y: y/z^3 */ - secp256k1_fe z; - int infinity; /* whether this represents the point at infinity */ -} secp256k1_gej; - -#define SECP256K1_GEJ_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1), 0} -#define SECP256K1_GEJ_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} - -typedef struct { - secp256k1_fe_storage x; - secp256k1_fe_storage y; -} secp256k1_ge_storage; - -#define SECP256K1_GE_STORAGE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_STORAGE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_STORAGE_CONST((i),(j),(k),(l),(m),(n),(o),(p))} - -#define SECP256K1_GE_STORAGE_CONST_GET(t) SECP256K1_FE_STORAGE_CONST_GET(t.x), SECP256K1_FE_STORAGE_CONST_GET(t.y) - -/** Set a group element equal to the point with given X and Y coordinates */ -static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y); - -/** Set a group element (affine) equal to the point with the given X coordinate - * and a Y coordinate that is a quadratic residue modulo p. The return value - * is true iff a coordinate with the given X coordinate exists. - */ -static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x); - -/** Set a group element (affine) equal to the point with the given X coordinate, and given oddness - * for Y. Return value indicates whether the result is valid. */ -static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd); - -/** Check whether a group element is the point at infinity. */ -static int secp256k1_ge_is_infinity(const secp256k1_ge *a); - -/** Check whether a group element is valid (i.e., on the curve). */ -static int secp256k1_ge_is_valid_var(const secp256k1_ge *a); - -static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a); - -/** Set a group element equal to another which is given in jacobian coordinates */ -static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a); - -/** Set a batch of group elements equal to the inputs given in jacobian coordinates */ -static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb); - -/** Set a batch of group elements equal to the inputs given in jacobian - * coordinates (with known z-ratios). zr must contain the known z-ratios such - * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. */ -static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len); - -/** Bring a batch inputs given in jacobian coordinates (with known z-ratios) to - * the same global z "denominator". zr must contain the known z-ratios such - * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. The x and y - * coordinates of the result are stored in r, the common z coordinate is - * stored in globalz. */ -static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp256k1_fe *globalz, const secp256k1_gej *a, const secp256k1_fe *zr); - -/** Set a group element (affine) equal to the point at infinity. */ -static void secp256k1_ge_set_infinity(secp256k1_ge *r); - -/** Set a group element (jacobian) equal to the point at infinity. */ -static void secp256k1_gej_set_infinity(secp256k1_gej *r); - -/** Set a group element (jacobian) equal to another which is given in affine coordinates. */ -static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a); - -/** Compare the X coordinate of a group element (jacobian). */ -static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a); - -/** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ -static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a); - -/** Check whether a group element is the point at infinity. */ -static int secp256k1_gej_is_infinity(const secp256k1_gej *a); - -/** Check whether a group element's y coordinate is a quadratic residue. */ -static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a); - -/** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). - * a may not be zero. Constant time. */ -static void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); - -/** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). */ -static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); - -/** Set r equal to the sum of a and b. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */ -static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr); - -/** Set r equal to the sum of a and b (with b given in affine coordinates, and not infinity). */ -static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b); - -/** Set r equal to the sum of a and b (with b given in affine coordinates). This is more efficient - than secp256k1_gej_add_var. It is identical to secp256k1_gej_add_ge but without constant-time - guarantee, and b is allowed to be infinity. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */ -static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr); - -/** Set r equal to the sum of a and b (with the inverse of b's Z coordinate passed as bzinv). */ -static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv); - -#ifdef USE_ENDOMORPHISM -/** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */ -static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a); -#endif - -/** Clear a secp256k1_gej to prevent leaking sensitive information. */ -static void secp256k1_gej_clear(secp256k1_gej *r); - -/** Clear a secp256k1_ge to prevent leaking sensitive information. */ -static void secp256k1_ge_clear(secp256k1_ge *r); - -/** Convert a group element to the storage type. */ -static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a); - -/** Convert a group element back from the storage type. */ -static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a); - -/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag); - -/** Rescale a jacobian point by b which must be non-zero. Constant-time. */ -static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *b); - -#endif /* SECP256K1_GROUP_H */ diff --git a/Sources/secp256k1/src/group_impl.h b/Sources/secp256k1/src/group_impl.h deleted file mode 100644 index b1ace87..0000000 --- a/Sources/secp256k1/src/group_impl.h +++ /dev/null @@ -1,706 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_GROUP_IMPL_H -#define SECP256K1_GROUP_IMPL_H - -#include "num.h" -#include "field.h" -#include "group.h" - -/* These points can be generated in sage as follows: - * - * 0. Setup a worksheet with the following parameters. - * b = 4 # whatever CURVE_B will be set to - * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) - * C = EllipticCurve ([F (0), F (b)]) - * - * 1. Determine all the small orders available to you. (If there are - * no satisfactory ones, go back and change b.) - * print C.order().factor(limit=1000) - * - * 2. Choose an order as one of the prime factors listed in the above step. - * (You can also multiply some to get a composite order, though the - * tests will crash trying to invert scalars during signing.) We take a - * random point and scale it to drop its order to the desired value. - * There is some probability this won't work; just try again. - * order = 199 - * P = C.random_point() - * P = (int(P.order()) / int(order)) * P - * assert(P.order() == order) - * - * 3. Print the values. You'll need to use a vim macro or something to - * split the hex output into 4-byte chunks. - * print "%x %x" % P.xy() - */ -#if defined(EXHAUSTIVE_TEST_ORDER) -# if EXHAUSTIVE_TEST_ORDER == 199 -const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( - 0xFA7CC9A7, 0x0737F2DB, 0xA749DD39, 0x2B4FB069, - 0x3B017A7D, 0xA808C2F1, 0xFB12940C, 0x9EA66C18, - 0x78AC123A, 0x5ED8AEF3, 0x8732BC91, 0x1F3A2868, - 0x48DF246C, 0x808DAE72, 0xCFE52572, 0x7F0501ED -); - -const int CURVE_B = 4; -# elif EXHAUSTIVE_TEST_ORDER == 13 -const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( - 0xedc60018, 0xa51a786b, 0x2ea91f4d, 0x4c9416c0, - 0x9de54c3b, 0xa1316554, 0x6cf4345c, 0x7277ef15, - 0x54cb1b6b, 0xdc8c1273, 0x087844ea, 0x43f4603e, - 0x0eaf9a43, 0xf6effe55, 0x939f806d, 0x37adf8ac -); -const int CURVE_B = 2; -# else -# error No known generator for the specified exhaustive test group order. -# endif -#else -/** Generator for secp256k1, value 'g' defined in - * "Standards for Efficient Cryptography" (SEC2) 2.7.1. - */ -static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( - 0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL, - 0x029BFCDBUL, 0x2DCE28D9UL, 0x59F2815BUL, 0x16F81798UL, - 0x483ADA77UL, 0x26A3C465UL, 0x5DA4FBFCUL, 0x0E1108A8UL, - 0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL -); - -const int CURVE_B = 7; -#endif - -static void secp256k1_ge_set_gej_zinv(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zi) { - secp256k1_fe zi2; - secp256k1_fe zi3; - secp256k1_fe_sqr(&zi2, zi); - secp256k1_fe_mul(&zi3, &zi2, zi); - secp256k1_fe_mul(&r->x, &a->x, &zi2); - secp256k1_fe_mul(&r->y, &a->y, &zi3); - r->infinity = a->infinity; -} - -static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y) { - r->infinity = 0; - r->x = *x; - r->y = *y; -} - -static int secp256k1_ge_is_infinity(const secp256k1_ge *a) { - return a->infinity; -} - -static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a) { - *r = *a; - secp256k1_fe_normalize_weak(&r->y); - secp256k1_fe_negate(&r->y, &r->y, 1); -} - -static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a) { - secp256k1_fe z2, z3; - r->infinity = a->infinity; - secp256k1_fe_inv(&a->z, &a->z); - secp256k1_fe_sqr(&z2, &a->z); - secp256k1_fe_mul(&z3, &a->z, &z2); - secp256k1_fe_mul(&a->x, &a->x, &z2); - secp256k1_fe_mul(&a->y, &a->y, &z3); - secp256k1_fe_set_int(&a->z, 1); - r->x = a->x; - r->y = a->y; -} - -static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) { - secp256k1_fe z2, z3; - r->infinity = a->infinity; - if (a->infinity) { - return; - } - secp256k1_fe_inv_var(&a->z, &a->z); - secp256k1_fe_sqr(&z2, &a->z); - secp256k1_fe_mul(&z3, &a->z, &z2); - secp256k1_fe_mul(&a->x, &a->x, &z2); - secp256k1_fe_mul(&a->y, &a->y, &z3); - secp256k1_fe_set_int(&a->z, 1); - r->x = a->x; - r->y = a->y; -} - -static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb) { - secp256k1_fe *az; - secp256k1_fe *azi; - size_t i; - size_t count = 0; - az = (secp256k1_fe *)checked_malloc(cb, sizeof(secp256k1_fe) * len); - for (i = 0; i < len; i++) { - if (!a[i].infinity) { - az[count++] = a[i].z; - } - } - - azi = (secp256k1_fe *)checked_malloc(cb, sizeof(secp256k1_fe) * count); - secp256k1_fe_inv_all_var(azi, az, count); - free(az); - - count = 0; - for (i = 0; i < len; i++) { - r[i].infinity = a[i].infinity; - if (!a[i].infinity) { - secp256k1_ge_set_gej_zinv(&r[i], &a[i], &azi[count++]); - } - } - free(azi); -} - -static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len) { - size_t i = len - 1; - secp256k1_fe zi; - - if (len > 0) { - /* Compute the inverse of the last z coordinate, and use it to compute the last affine output. */ - secp256k1_fe_inv(&zi, &a[i].z); - secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zi); - - /* Work out way backwards, using the z-ratios to scale the x/y values. */ - while (i > 0) { - secp256k1_fe_mul(&zi, &zi, &zr[i]); - i--; - secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zi); - } - } -} - -static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp256k1_fe *globalz, const secp256k1_gej *a, const secp256k1_fe *zr) { - size_t i = len - 1; - secp256k1_fe zs; - - if (len > 0) { - /* The z of the final point gives us the "global Z" for the table. */ - r[i].x = a[i].x; - r[i].y = a[i].y; - *globalz = a[i].z; - r[i].infinity = 0; - zs = zr[i]; - - /* Work our way backwards, using the z-ratios to scale the x/y values. */ - while (i > 0) { - if (i != len - 1) { - secp256k1_fe_mul(&zs, &zs, &zr[i]); - } - i--; - secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zs); - } - } -} - -static void secp256k1_gej_set_infinity(secp256k1_gej *r) { - r->infinity = 1; - secp256k1_fe_clear(&r->x); - secp256k1_fe_clear(&r->y); - secp256k1_fe_clear(&r->z); -} - -static void secp256k1_ge_set_infinity(secp256k1_ge *r) { - r->infinity = 1; - secp256k1_fe_clear(&r->x); - secp256k1_fe_clear(&r->y); -} - -static void secp256k1_gej_clear(secp256k1_gej *r) { - r->infinity = 0; - secp256k1_fe_clear(&r->x); - secp256k1_fe_clear(&r->y); - secp256k1_fe_clear(&r->z); -} - -static void secp256k1_ge_clear(secp256k1_ge *r) { - r->infinity = 0; - secp256k1_fe_clear(&r->x); - secp256k1_fe_clear(&r->y); -} - -static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x) { - secp256k1_fe x2, x3, c; - r->x = *x; - secp256k1_fe_sqr(&x2, x); - secp256k1_fe_mul(&x3, x, &x2); - r->infinity = 0; - secp256k1_fe_set_int(&c, CURVE_B); - secp256k1_fe_add(&c, &x3); - return secp256k1_fe_sqrt(&r->y, &c); -} - -static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd) { - if (!secp256k1_ge_set_xquad(r, x)) { - return 0; - } - secp256k1_fe_normalize_var(&r->y); - if (secp256k1_fe_is_odd(&r->y) != odd) { - secp256k1_fe_negate(&r->y, &r->y, 1); - } - return 1; - -} - -static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a) { - r->infinity = a->infinity; - r->x = a->x; - r->y = a->y; - secp256k1_fe_set_int(&r->z, 1); -} - -static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a) { - secp256k1_fe r, r2; - VERIFY_CHECK(!a->infinity); - secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x); - r2 = a->x; secp256k1_fe_normalize_weak(&r2); - return secp256k1_fe_equal_var(&r, &r2); -} - -static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a) { - r->infinity = a->infinity; - r->x = a->x; - r->y = a->y; - r->z = a->z; - secp256k1_fe_normalize_weak(&r->y); - secp256k1_fe_negate(&r->y, &r->y, 1); -} - -static int secp256k1_gej_is_infinity(const secp256k1_gej *a) { - return a->infinity; -} - -static int secp256k1_gej_is_valid_var(const secp256k1_gej *a) { - secp256k1_fe y2, x3, z2, z6; - if (a->infinity) { - return 0; - } - /** y^2 = x^3 + 7 - * (Y/Z^3)^2 = (X/Z^2)^3 + 7 - * Y^2 / Z^6 = X^3 / Z^6 + 7 - * Y^2 = X^3 + 7*Z^6 - */ - secp256k1_fe_sqr(&y2, &a->y); - secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); - secp256k1_fe_sqr(&z2, &a->z); - secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2); - secp256k1_fe_mul_int(&z6, CURVE_B); - secp256k1_fe_add(&x3, &z6); - secp256k1_fe_normalize_weak(&x3); - return secp256k1_fe_equal_var(&y2, &x3); -} - -static int secp256k1_ge_is_valid_var(const secp256k1_ge *a) { - secp256k1_fe y2, x3, c; - if (a->infinity) { - return 0; - } - /* y^2 = x^3 + 7 */ - secp256k1_fe_sqr(&y2, &a->y); - secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); - secp256k1_fe_set_int(&c, CURVE_B); - secp256k1_fe_add(&x3, &c); - secp256k1_fe_normalize_weak(&x3); - return secp256k1_fe_equal_var(&y2, &x3); -} - -static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { - /* Operations: 3 mul, 4 sqr, 0 normalize, 12 mul_int/add/negate. - * - * Note that there is an implementation described at - * https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l - * which trades a multiply for a square, but in practice this is actually slower, - * mainly because it requires more normalizations. - */ - secp256k1_fe t1,t2,t3,t4; - /** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity, - * Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have - * y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p. - * - * Having said this, if this function receives a point on a sextic twist, e.g. by - * a fault attack, it is possible for y to be 0. This happens for y^2 = x^3 + 6, - * since -6 does have a cube root mod p. For this point, this function will not set - * the infinity flag even though the point doubles to infinity, and the result - * point will be gibberish (z = 0 but infinity = 0). - */ - r->infinity = a->infinity; - if (r->infinity) { - if (rzr != NULL) { - secp256k1_fe_set_int(rzr, 1); - } - return; - } - - if (rzr != NULL) { - *rzr = a->y; - secp256k1_fe_normalize_weak(rzr); - secp256k1_fe_mul_int(rzr, 2); - } - - secp256k1_fe_mul(&r->z, &a->z, &a->y); - secp256k1_fe_mul_int(&r->z, 2); /* Z' = 2*Y*Z (2) */ - secp256k1_fe_sqr(&t1, &a->x); - secp256k1_fe_mul_int(&t1, 3); /* T1 = 3*X^2 (3) */ - secp256k1_fe_sqr(&t2, &t1); /* T2 = 9*X^4 (1) */ - secp256k1_fe_sqr(&t3, &a->y); - secp256k1_fe_mul_int(&t3, 2); /* T3 = 2*Y^2 (2) */ - secp256k1_fe_sqr(&t4, &t3); - secp256k1_fe_mul_int(&t4, 2); /* T4 = 8*Y^4 (2) */ - secp256k1_fe_mul(&t3, &t3, &a->x); /* T3 = 2*X*Y^2 (1) */ - r->x = t3; - secp256k1_fe_mul_int(&r->x, 4); /* X' = 8*X*Y^2 (4) */ - secp256k1_fe_negate(&r->x, &r->x, 4); /* X' = -8*X*Y^2 (5) */ - secp256k1_fe_add(&r->x, &t2); /* X' = 9*X^4 - 8*X*Y^2 (6) */ - secp256k1_fe_negate(&t2, &t2, 1); /* T2 = -9*X^4 (2) */ - secp256k1_fe_mul_int(&t3, 6); /* T3 = 12*X*Y^2 (6) */ - secp256k1_fe_add(&t3, &t2); /* T3 = 12*X*Y^2 - 9*X^4 (8) */ - secp256k1_fe_mul(&r->y, &t1, &t3); /* Y' = 36*X^3*Y^2 - 27*X^6 (1) */ - secp256k1_fe_negate(&t2, &t4, 2); /* T2 = -8*Y^4 (3) */ - secp256k1_fe_add(&r->y, &t2); /* Y' = 36*X^3*Y^2 - 27*X^6 - 8*Y^4 (4) */ -} - -static SECP256K1_INLINE void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { - VERIFY_CHECK(!secp256k1_gej_is_infinity(a)); - secp256k1_gej_double_var(r, a, rzr); -} - -static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr) { - /* Operations: 12 mul, 4 sqr, 2 normalize, 12 mul_int/add/negate */ - secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; - - if (a->infinity) { - VERIFY_CHECK(rzr == NULL); - *r = *b; - return; - } - - if (b->infinity) { - if (rzr != NULL) { - secp256k1_fe_set_int(rzr, 1); - } - *r = *a; - return; - } - - r->infinity = 0; - secp256k1_fe_sqr(&z22, &b->z); - secp256k1_fe_sqr(&z12, &a->z); - secp256k1_fe_mul(&u1, &a->x, &z22); - secp256k1_fe_mul(&u2, &b->x, &z12); - secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z); - secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); - secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); - if (secp256k1_fe_normalizes_to_zero_var(&h)) { - if (secp256k1_fe_normalizes_to_zero_var(&i)) { - secp256k1_gej_double_var(r, a, rzr); - } else { - if (rzr != NULL) { - secp256k1_fe_set_int(rzr, 0); - } - r->infinity = 1; - } - return; - } - secp256k1_fe_sqr(&i2, &i); - secp256k1_fe_sqr(&h2, &h); - secp256k1_fe_mul(&h3, &h, &h2); - secp256k1_fe_mul(&h, &h, &b->z); - if (rzr != NULL) { - *rzr = h; - } - secp256k1_fe_mul(&r->z, &a->z, &h); - secp256k1_fe_mul(&t, &u1, &h2); - r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); - secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); - secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); - secp256k1_fe_add(&r->y, &h3); -} - -static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr) { - /* 8 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */ - secp256k1_fe z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; - if (a->infinity) { - VERIFY_CHECK(rzr == NULL); - secp256k1_gej_set_ge(r, b); - return; - } - if (b->infinity) { - if (rzr != NULL) { - secp256k1_fe_set_int(rzr, 1); - } - *r = *a; - return; - } - r->infinity = 0; - - secp256k1_fe_sqr(&z12, &a->z); - u1 = a->x; secp256k1_fe_normalize_weak(&u1); - secp256k1_fe_mul(&u2, &b->x, &z12); - s1 = a->y; secp256k1_fe_normalize_weak(&s1); - secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); - secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); - if (secp256k1_fe_normalizes_to_zero_var(&h)) { - if (secp256k1_fe_normalizes_to_zero_var(&i)) { - secp256k1_gej_double_var(r, a, rzr); - } else { - if (rzr != NULL) { - secp256k1_fe_set_int(rzr, 0); - } - r->infinity = 1; - } - return; - } - secp256k1_fe_sqr(&i2, &i); - secp256k1_fe_sqr(&h2, &h); - secp256k1_fe_mul(&h3, &h, &h2); - if (rzr != NULL) { - *rzr = h; - } - secp256k1_fe_mul(&r->z, &a->z, &h); - secp256k1_fe_mul(&t, &u1, &h2); - r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); - secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); - secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); - secp256k1_fe_add(&r->y, &h3); -} - -static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv) { - /* 9 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */ - secp256k1_fe az, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; - - if (b->infinity) { - *r = *a; - return; - } - if (a->infinity) { - secp256k1_fe bzinv2, bzinv3; - r->infinity = b->infinity; - secp256k1_fe_sqr(&bzinv2, bzinv); - secp256k1_fe_mul(&bzinv3, &bzinv2, bzinv); - secp256k1_fe_mul(&r->x, &b->x, &bzinv2); - secp256k1_fe_mul(&r->y, &b->y, &bzinv3); - secp256k1_fe_set_int(&r->z, 1); - return; - } - r->infinity = 0; - - /** We need to calculate (rx,ry,rz) = (ax,ay,az) + (bx,by,1/bzinv). Due to - * secp256k1's isomorphism we can multiply the Z coordinates on both sides - * by bzinv, and get: (rx,ry,rz*bzinv) = (ax,ay,az*bzinv) + (bx,by,1). - * This means that (rx,ry,rz) can be calculated as - * (ax,ay,az*bzinv) + (bx,by,1), when not applying the bzinv factor to rz. - * The variable az below holds the modified Z coordinate for a, which is used - * for the computation of rx and ry, but not for rz. - */ - secp256k1_fe_mul(&az, &a->z, bzinv); - - secp256k1_fe_sqr(&z12, &az); - u1 = a->x; secp256k1_fe_normalize_weak(&u1); - secp256k1_fe_mul(&u2, &b->x, &z12); - s1 = a->y; secp256k1_fe_normalize_weak(&s1); - secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &az); - secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); - if (secp256k1_fe_normalizes_to_zero_var(&h)) { - if (secp256k1_fe_normalizes_to_zero_var(&i)) { - secp256k1_gej_double_var(r, a, NULL); - } else { - r->infinity = 1; - } - return; - } - secp256k1_fe_sqr(&i2, &i); - secp256k1_fe_sqr(&h2, &h); - secp256k1_fe_mul(&h3, &h, &h2); - r->z = a->z; secp256k1_fe_mul(&r->z, &r->z, &h); - secp256k1_fe_mul(&t, &u1, &h2); - r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); - secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); - secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); - secp256k1_fe_add(&r->y, &h3); -} - - -static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b) { - /* Operations: 7 mul, 5 sqr, 4 normalize, 21 mul_int/add/negate/cmov */ - static const secp256k1_fe fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_fe zz, u1, u2, s1, s2, t, tt, m, n, q, rr; - secp256k1_fe m_alt, rr_alt; - int infinity, degenerate; - VERIFY_CHECK(!b->infinity); - VERIFY_CHECK(a->infinity == 0 || a->infinity == 1); - - /** In: - * Eric Brier and Marc Joye, Weierstrass Elliptic Curves and Side-Channel Attacks. - * In D. Naccache and P. Paillier, Eds., Public Key Cryptography, vol. 2274 of Lecture Notes in Computer Science, pages 335-345. Springer-Verlag, 2002. - * we find as solution for a unified addition/doubling formula: - * lambda = ((x1 + x2)^2 - x1 * x2 + a) / (y1 + y2), with a = 0 for secp256k1's curve equation. - * x3 = lambda^2 - (x1 + x2) - * 2*y3 = lambda * (x1 + x2 - 2 * x3) - (y1 + y2). - * - * Substituting x_i = Xi / Zi^2 and yi = Yi / Zi^3, for i=1,2,3, gives: - * U1 = X1*Z2^2, U2 = X2*Z1^2 - * S1 = Y1*Z2^3, S2 = Y2*Z1^3 - * Z = Z1*Z2 - * T = U1+U2 - * M = S1+S2 - * Q = T*M^2 - * R = T^2-U1*U2 - * X3 = 4*(R^2-Q) - * Y3 = 4*(R*(3*Q-2*R^2)-M^4) - * Z3 = 2*M*Z - * (Note that the paper uses xi = Xi / Zi and yi = Yi / Zi instead.) - * - * This formula has the benefit of being the same for both addition - * of distinct points and doubling. However, it breaks down in the - * case that either point is infinity, or that y1 = -y2. We handle - * these cases in the following ways: - * - * - If b is infinity we simply bail by means of a VERIFY_CHECK. - * - * - If a is infinity, we detect this, and at the end of the - * computation replace the result (which will be meaningless, - * but we compute to be constant-time) with b.x : b.y : 1. - * - * - If a = -b, we have y1 = -y2, which is a degenerate case. - * But here the answer is infinity, so we simply set the - * infinity flag of the result, overriding the computed values - * without even needing to cmov. - * - * - If y1 = -y2 but x1 != x2, which does occur thanks to certain - * properties of our curve (specifically, 1 has nontrivial cube - * roots in our field, and the curve equation has no x coefficient) - * then the answer is not infinity but also not given by the above - * equation. In this case, we cmov in place an alternate expression - * for lambda. Specifically (y1 - y2)/(x1 - x2). Where both these - * expressions for lambda are defined, they are equal, and can be - * obtained from each other by multiplication by (y1 + y2)/(y1 + y2) - * then substitution of x^3 + 7 for y^2 (using the curve equation). - * For all pairs of nonzero points (a, b) at least one is defined, - * so this covers everything. - */ - - secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */ - u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */ - secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */ - s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */ - secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z1^2 (1) */ - secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */ - t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */ - m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */ - secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */ - secp256k1_fe_negate(&m_alt, &u2, 1); /* Malt = -X2*Z1^2 */ - secp256k1_fe_mul(&tt, &u1, &m_alt); /* tt = -U1*U2 (2) */ - secp256k1_fe_add(&rr, &tt); /* rr = R = T^2-U1*U2 (3) */ - /** If lambda = R/M = 0/0 we have a problem (except in the "trivial" - * case that Z = z1z2 = 0, and this is special-cased later on). */ - degenerate = secp256k1_fe_normalizes_to_zero(&m) & - secp256k1_fe_normalizes_to_zero(&rr); - /* This only occurs when y1 == -y2 and x1^3 == x2^3, but x1 != x2. - * This means either x1 == beta*x2 or beta*x1 == x2, where beta is - * a nontrivial cube root of one. In either case, an alternate - * non-indeterminate expression for lambda is (y1 - y2)/(x1 - x2), - * so we set R/M equal to this. */ - rr_alt = s1; - secp256k1_fe_mul_int(&rr_alt, 2); /* rr = Y1*Z2^3 - Y2*Z1^3 (2) */ - secp256k1_fe_add(&m_alt, &u1); /* Malt = X1*Z2^2 - X2*Z1^2 */ - - secp256k1_fe_cmov(&rr_alt, &rr, !degenerate); - secp256k1_fe_cmov(&m_alt, &m, !degenerate); - /* Now Ralt / Malt = lambda and is guaranteed not to be 0/0. - * From here on out Ralt and Malt represent the numerator - * and denominator of lambda; R and M represent the explicit - * expressions x1^2 + x2^2 + x1x2 and y1 + y2. */ - secp256k1_fe_sqr(&n, &m_alt); /* n = Malt^2 (1) */ - secp256k1_fe_mul(&q, &n, &t); /* q = Q = T*Malt^2 (1) */ - /* These two lines use the observation that either M == Malt or M == 0, - * so M^3 * Malt is either Malt^4 (which is computed by squaring), or - * zero (which is "computed" by cmov). So the cost is one squaring - * versus two multiplications. */ - secp256k1_fe_sqr(&n, &n); - secp256k1_fe_cmov(&n, &m, degenerate); /* n = M^3 * Malt (2) */ - secp256k1_fe_sqr(&t, &rr_alt); /* t = Ralt^2 (1) */ - secp256k1_fe_mul(&r->z, &a->z, &m_alt); /* r->z = Malt*Z (1) */ - infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity); - secp256k1_fe_mul_int(&r->z, 2); /* r->z = Z3 = 2*Malt*Z (2) */ - secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */ - secp256k1_fe_add(&t, &q); /* t = Ralt^2-Q (3) */ - secp256k1_fe_normalize_weak(&t); - r->x = t; /* r->x = Ralt^2-Q (1) */ - secp256k1_fe_mul_int(&t, 2); /* t = 2*x3 (2) */ - secp256k1_fe_add(&t, &q); /* t = 2*x3 - Q: (4) */ - secp256k1_fe_mul(&t, &t, &rr_alt); /* t = Ralt*(2*x3 - Q) (1) */ - secp256k1_fe_add(&t, &n); /* t = Ralt*(2*x3 - Q) + M^3*Malt (3) */ - secp256k1_fe_negate(&r->y, &t, 3); /* r->y = Ralt*(Q - 2x3) - M^3*Malt (4) */ - secp256k1_fe_normalize_weak(&r->y); - secp256k1_fe_mul_int(&r->x, 4); /* r->x = X3 = 4*(Ralt^2-Q) */ - secp256k1_fe_mul_int(&r->y, 4); /* r->y = Y3 = 4*Ralt*(Q - 2x3) - 4*M^3*Malt (4) */ - - /** In case a->infinity == 1, replace r with (b->x, b->y, 1). */ - secp256k1_fe_cmov(&r->x, &b->x, a->infinity); - secp256k1_fe_cmov(&r->y, &b->y, a->infinity); - secp256k1_fe_cmov(&r->z, &fe_1, a->infinity); - r->infinity = infinity; -} - -static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *s) { - /* Operations: 4 mul, 1 sqr */ - secp256k1_fe zz; - VERIFY_CHECK(!secp256k1_fe_is_zero(s)); - secp256k1_fe_sqr(&zz, s); - secp256k1_fe_mul(&r->x, &r->x, &zz); /* r->x *= s^2 */ - secp256k1_fe_mul(&r->y, &r->y, &zz); - secp256k1_fe_mul(&r->y, &r->y, s); /* r->y *= s^3 */ - secp256k1_fe_mul(&r->z, &r->z, s); /* r->z *= s */ -} - -static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a) { - secp256k1_fe x, y; - VERIFY_CHECK(!a->infinity); - x = a->x; - secp256k1_fe_normalize(&x); - y = a->y; - secp256k1_fe_normalize(&y); - secp256k1_fe_to_storage(&r->x, &x); - secp256k1_fe_to_storage(&r->y, &y); -} - -static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a) { - secp256k1_fe_from_storage(&r->x, &a->x); - secp256k1_fe_from_storage(&r->y, &a->y); - r->infinity = 0; -} - -static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag) { - secp256k1_fe_storage_cmov(&r->x, &a->x, flag); - secp256k1_fe_storage_cmov(&r->y, &a->y, flag); -} - -#ifdef USE_ENDOMORPHISM -static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a) { - static const secp256k1_fe beta = SECP256K1_FE_CONST( - 0x7ae96a2bul, 0x657c0710ul, 0x6e64479eul, 0xac3434e9ul, - 0x9cf04975ul, 0x12f58995ul, 0xc1396c28ul, 0x719501eeul - ); - *r = *a; - secp256k1_fe_mul(&r->x, &r->x, &beta); -} -#endif - -static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a) { - secp256k1_fe yz; - - if (a->infinity) { - return 0; - } - - /* We rely on the fact that the Jacobi symbol of 1 / a->z^3 is the same as - * that of a->z. Thus a->y / a->z^3 is a quadratic residue iff a->y * a->z - is */ - secp256k1_fe_mul(&yz, &a->y, &a->z); - return secp256k1_fe_is_quad_var(&yz); -} - -#endif /* SECP256K1_GROUP_IMPL_H */ diff --git a/Sources/secp256k1/src/hash.h b/Sources/secp256k1/src/hash.h deleted file mode 100644 index de26e4b..0000000 --- a/Sources/secp256k1/src/hash.h +++ /dev/null @@ -1,41 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_HASH_H -#define SECP256K1_HASH_H - -#include -#include - -typedef struct { - uint32_t s[8]; - uint32_t buf[16]; /* In big endian */ - size_t bytes; -} secp256k1_sha256; - -static void secp256k1_sha256_initialize(secp256k1_sha256 *hash); -static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size); -static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32); - -typedef struct { - secp256k1_sha256 inner, outer; -} secp256k1_hmac_sha256; - -static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size); -static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size); -static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32); - -typedef struct { - unsigned char v[32]; - unsigned char k[32]; - int retry; -} secp256k1_rfc6979_hmac_sha256; - -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); -static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); -static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng); - -#endif /* SECP256K1_HASH_H */ diff --git a/Sources/secp256k1/src/hash_impl.h b/Sources/secp256k1/src/hash_impl.h deleted file mode 100644 index 009f26b..0000000 --- a/Sources/secp256k1/src/hash_impl.h +++ /dev/null @@ -1,282 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_HASH_IMPL_H -#define SECP256K1_HASH_IMPL_H - -#include "hash.h" - -#include -#include -#include - -#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) -#define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) -#define Sigma0(x) (((x) >> 2 | (x) << 30) ^ ((x) >> 13 | (x) << 19) ^ ((x) >> 22 | (x) << 10)) -#define Sigma1(x) (((x) >> 6 | (x) << 26) ^ ((x) >> 11 | (x) << 21) ^ ((x) >> 25 | (x) << 7)) -#define sigma0(x) (((x) >> 7 | (x) << 25) ^ ((x) >> 18 | (x) << 14) ^ ((x) >> 3)) -#define sigma1(x) (((x) >> 17 | (x) << 15) ^ ((x) >> 19 | (x) << 13) ^ ((x) >> 10)) - -#define Round(a,b,c,d,e,f,g,h,k,w) do { \ - uint32_t t1 = (h) + Sigma1(e) + Ch((e), (f), (g)) + (k) + (w); \ - uint32_t t2 = Sigma0(a) + Maj((a), (b), (c)); \ - (d) += t1; \ - (h) = t1 + t2; \ -} while(0) - -#ifdef WORDS_BIGENDIAN -#define BE32(x) (x) -#else -#define BE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24)) -#endif - -static void secp256k1_sha256_initialize(secp256k1_sha256 *hash) { - hash->s[0] = 0x6a09e667ul; - hash->s[1] = 0xbb67ae85ul; - hash->s[2] = 0x3c6ef372ul; - hash->s[3] = 0xa54ff53aul; - hash->s[4] = 0x510e527ful; - hash->s[5] = 0x9b05688cul; - hash->s[6] = 0x1f83d9abul; - hash->s[7] = 0x5be0cd19ul; - hash->bytes = 0; -} - -/** Perform one SHA-256 transformation, processing 16 big endian 32-bit words. */ -static void secp256k1_sha256_transform(uint32_t* s, const uint32_t* chunk) { - uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; - uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; - - Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = BE32(chunk[0])); - Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = BE32(chunk[1])); - Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = BE32(chunk[2])); - Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = BE32(chunk[3])); - Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = BE32(chunk[4])); - Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = BE32(chunk[5])); - Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = BE32(chunk[6])); - Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = BE32(chunk[7])); - Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = BE32(chunk[8])); - Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = BE32(chunk[9])); - Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = BE32(chunk[10])); - Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = BE32(chunk[11])); - Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = BE32(chunk[12])); - Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = BE32(chunk[13])); - Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = BE32(chunk[14])); - Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = BE32(chunk[15])); - - Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1)); - Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2)); - Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3)); - Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4)); - Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5)); - Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6)); - Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7)); - Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8)); - Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9)); - Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0)); - - Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1)); - Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2)); - Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3)); - Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4)); - Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5)); - Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6)); - Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7)); - Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8)); - Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9)); - Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0)); - - Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1)); - Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2)); - Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3)); - Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4)); - Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5)); - Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6)); - Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7)); - Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8)); - Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9)); - Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0)); - - s[0] += a; - s[1] += b; - s[2] += c; - s[3] += d; - s[4] += e; - s[5] += f; - s[6] += g; - s[7] += h; -} - -static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t len) { - size_t bufsize = hash->bytes & 0x3F; - hash->bytes += len; - while (bufsize + len >= 64) { - /* Fill the buffer, and process it. */ - size_t chunk_len = 64 - bufsize; - memcpy(((unsigned char*)hash->buf) + bufsize, data, chunk_len); - data += chunk_len; - len -= chunk_len; - secp256k1_sha256_transform(hash->s, hash->buf); - bufsize = 0; - } - if (len) { - /* Fill the buffer with what remains. */ - memcpy(((unsigned char*)hash->buf) + bufsize, data, len); - } -} - -static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32) { - static const unsigned char pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - uint32_t sizedesc[2]; - uint32_t out[8]; - int i = 0; - sizedesc[0] = BE32(hash->bytes >> 29); - sizedesc[1] = BE32(hash->bytes << 3); - secp256k1_sha256_write(hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64)); - secp256k1_sha256_write(hash, (const unsigned char*)sizedesc, 8); - for (i = 0; i < 8; i++) { - out[i] = BE32(hash->s[i]); - hash->s[i] = 0; - } - memcpy(out32, (const unsigned char*)out, 32); -} - -static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t keylen) { - size_t n; - unsigned char rkey[64]; - if (keylen <= sizeof(rkey)) { - memcpy(rkey, key, keylen); - memset(rkey + keylen, 0, sizeof(rkey) - keylen); - } else { - secp256k1_sha256 sha256; - secp256k1_sha256_initialize(&sha256); - secp256k1_sha256_write(&sha256, key, keylen); - secp256k1_sha256_finalize(&sha256, rkey); - memset(rkey + 32, 0, 32); - } - - secp256k1_sha256_initialize(&hash->outer); - for (n = 0; n < sizeof(rkey); n++) { - rkey[n] ^= 0x5c; - } - secp256k1_sha256_write(&hash->outer, rkey, sizeof(rkey)); - - secp256k1_sha256_initialize(&hash->inner); - for (n = 0; n < sizeof(rkey); n++) { - rkey[n] ^= 0x5c ^ 0x36; - } - secp256k1_sha256_write(&hash->inner, rkey, sizeof(rkey)); - memset(rkey, 0, sizeof(rkey)); -} - -static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size) { - secp256k1_sha256_write(&hash->inner, data, size); -} - -static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32) { - unsigned char temp[32]; - secp256k1_sha256_finalize(&hash->inner, temp); - secp256k1_sha256_write(&hash->outer, temp, 32); - memset(temp, 0, 32); - secp256k1_sha256_finalize(&hash->outer, out32); -} - - -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen) { - secp256k1_hmac_sha256 hmac; - static const unsigned char zero[1] = {0x00}; - static const unsigned char one[1] = {0x01}; - - memset(rng->v, 0x01, 32); /* RFC6979 3.2.b. */ - memset(rng->k, 0x00, 32); /* RFC6979 3.2.c. */ - - /* RFC6979 3.2.d. */ - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_write(&hmac, zero, 1); - secp256k1_hmac_sha256_write(&hmac, key, keylen); - secp256k1_hmac_sha256_finalize(&hmac, rng->k); - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_finalize(&hmac, rng->v); - - /* RFC6979 3.2.f. */ - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_write(&hmac, one, 1); - secp256k1_hmac_sha256_write(&hmac, key, keylen); - secp256k1_hmac_sha256_finalize(&hmac, rng->k); - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_finalize(&hmac, rng->v); - rng->retry = 0; -} - -static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen) { - /* RFC6979 3.2.h. */ - static const unsigned char zero[1] = {0x00}; - if (rng->retry) { - secp256k1_hmac_sha256 hmac; - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_write(&hmac, zero, 1); - secp256k1_hmac_sha256_finalize(&hmac, rng->k); - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_finalize(&hmac, rng->v); - } - - while (outlen > 0) { - secp256k1_hmac_sha256 hmac; - int now = outlen; - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_finalize(&hmac, rng->v); - if (now > 32) { - now = 32; - } - memcpy(out, rng->v, now); - out += now; - outlen -= now; - } - - rng->retry = 1; -} - -static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng) { - memset(rng->k, 0, 32); - memset(rng->v, 0, 32); - rng->retry = 0; -} - -#undef BE32 -#undef Round -#undef sigma1 -#undef sigma0 -#undef Sigma1 -#undef Sigma0 -#undef Maj -#undef Ch - -#endif /* SECP256K1_HASH_IMPL_H */ diff --git a/Sources/secp256k1/src/modules/ecdh/main_impl.h b/Sources/secp256k1/src/modules/ecdh/main_impl.h deleted file mode 100644 index 2409f10..0000000 --- a/Sources/secp256k1/src/modules/ecdh/main_impl.h +++ /dev/null @@ -1,54 +0,0 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_MODULE_ECDH_MAIN_H -#define SECP256K1_MODULE_ECDH_MAIN_H - -#include "secp256k1.h" -#include "../../ecmult_const_impl.h" - -int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *result, const secp256k1_pubkey *point, const unsigned char *scalar) { - int ret = 0; - int overflow = 0; - secp256k1_gej res; - secp256k1_ge pt; - secp256k1_scalar s; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(result != NULL); - ARG_CHECK(point != NULL); - ARG_CHECK(scalar != NULL); - - secp256k1_pubkey_load(ctx, &pt, point); - secp256k1_scalar_set_b32(&s, scalar, &overflow); - if (overflow || secp256k1_scalar_is_zero(&s)) { - ret = 0; - } else { - unsigned char x[32]; - unsigned char y[1]; - secp256k1_sha256 sha; - - secp256k1_ecmult_const(&res, &pt, &s, 256); - secp256k1_ge_set_gej(&pt, &res); - /* Compute a hash of the point in compressed form - * Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not - * expect its output to be secret and has a timing sidechannel. */ - secp256k1_fe_normalize(&pt.x); - secp256k1_fe_normalize(&pt.y); - secp256k1_fe_get_b32(x, &pt.x); - y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y); - - secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, y, sizeof(y)); - secp256k1_sha256_write(&sha, x, sizeof(x)); - secp256k1_sha256_finalize(&sha, result); - ret = 1; - } - - secp256k1_scalar_clear(&s); - return ret; -} - -#endif /* SECP256K1_MODULE_ECDH_MAIN_H */ diff --git a/Sources/secp256k1/src/modules/recovery/main_impl.h b/Sources/secp256k1/src/modules/recovery/main_impl.h deleted file mode 100755 index 537c537..0000000 --- a/Sources/secp256k1/src/modules/recovery/main_impl.h +++ /dev/null @@ -1,193 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_MODULE_RECOVERY_MAIN_H -#define SECP256K1_MODULE_RECOVERY_MAIN_H - -#include "secp256k1.h" - -static void secp256k1_ecdsa_recoverable_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const secp256k1_ecdsa_recoverable_signature* sig) { - (void)ctx; - if (sizeof(secp256k1_scalar) == 32) { - /* When the secp256k1_scalar type is exactly 32 byte, use its - * representation inside secp256k1_ecdsa_signature, as conversion is very fast. - * Note that secp256k1_ecdsa_signature_save must use the same representation. */ - memcpy(r, &sig->data[0], 32); - memcpy(s, &sig->data[32], 32); - } else { - secp256k1_scalar_set_b32(r, &sig->data[0], NULL); - secp256k1_scalar_set_b32(s, &sig->data[32], NULL); - } - *recid = sig->data[64]; -} - -static void secp256k1_ecdsa_recoverable_signature_save(secp256k1_ecdsa_recoverable_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s, int recid) { - if (sizeof(secp256k1_scalar) == 32) { - memcpy(&sig->data[0], r, 32); - memcpy(&sig->data[32], s, 32); - } else { - secp256k1_scalar_get_b32(&sig->data[0], r); - secp256k1_scalar_get_b32(&sig->data[32], s); - } - sig->data[64] = recid; -} - -int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature* sig, const unsigned char *input64, int recid) { - secp256k1_scalar r, s; - int ret = 1; - int overflow = 0; - - (void)ctx; - ARG_CHECK(sig != NULL); - ARG_CHECK(input64 != NULL); - ARG_CHECK(recid >= 0 && recid <= 3); - - secp256k1_scalar_set_b32(&r, &input64[0], &overflow); - ret &= !overflow; - secp256k1_scalar_set_b32(&s, &input64[32], &overflow); - ret &= !overflow; - if (ret) { - secp256k1_ecdsa_recoverable_signature_save(sig, &r, &s, recid); - } else { - memset(sig, 0, sizeof(*sig)); - } - return ret; -} - -int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature* sig) { - secp256k1_scalar r, s; - - (void)ctx; - ARG_CHECK(output64 != NULL); - ARG_CHECK(sig != NULL); - ARG_CHECK(recid != NULL); - - secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, recid, sig); - secp256k1_scalar_get_b32(&output64[0], &r); - secp256k1_scalar_get_b32(&output64[32], &s); - return 1; -} - -int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const secp256k1_ecdsa_recoverable_signature* sigin) { - secp256k1_scalar r, s; - int recid; - - (void)ctx; - ARG_CHECK(sig != NULL); - ARG_CHECK(sigin != NULL); - - secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, sigin); - secp256k1_ecdsa_signature_save(sig, &r, &s); - return 1; -} - -static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar* sigs, secp256k1_ge *pubkey, const secp256k1_scalar *message, int recid) { - unsigned char brx[32]; - secp256k1_fe fx; - secp256k1_ge x; - secp256k1_gej xj; - secp256k1_scalar rn, u1, u2; - secp256k1_gej qj; - int r; - - if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { - return 0; - } - - secp256k1_scalar_get_b32(brx, sigr); - r = secp256k1_fe_set_b32(&fx, brx); - (void)r; - VERIFY_CHECK(r); /* brx comes from a scalar, so is less than the order; certainly less than p */ - if (recid & 2) { - if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) { - return 0; - } - secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe); - } - if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) { - return 0; - } - secp256k1_gej_set_ge(&xj, &x); - secp256k1_scalar_inverse_var(&rn, sigr); - secp256k1_scalar_mul(&u1, &rn, message); - secp256k1_scalar_negate(&u1, &u1); - secp256k1_scalar_mul(&u2, &rn, sigs); - secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1); - secp256k1_ge_set_gej_var(pubkey, &qj); - return !secp256k1_gej_is_infinity(&qj); -} - -int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { - secp256k1_scalar r, s; - secp256k1_scalar sec, non, msg; - int recid; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(signature != NULL); - ARG_CHECK(seckey != NULL); - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; - } - - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - /* Fail if the secret key is invalid. */ - if (!overflow && !secp256k1_scalar_is_zero(&sec)) { - unsigned char nonce32[32]; - unsigned int count = 0; - secp256k1_scalar_set_b32(&msg, msg32, NULL); - while (1) { - ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, &recid)) { - break; - } - } - count++; - } - memset(nonce32, 0, 32); - secp256k1_scalar_clear(&msg); - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); - } - if (ret) { - secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid); - } else { - memset(signature, 0, sizeof(*signature)); - } - return ret; -} - -int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32) { - secp256k1_ge q; - secp256k1_scalar r, s; - secp256k1_scalar m; - int recid; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(signature != NULL); - ARG_CHECK(pubkey != NULL); - - secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature); - VERIFY_CHECK(recid >= 0 && recid < 4); /* should have been caught in parse_compact */ - secp256k1_scalar_set_b32(&m, msg32, NULL); - if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &r, &s, &q, &m, recid)) { - secp256k1_pubkey_save(pubkey, &q); - return 1; - } else { - memset(pubkey, 0, sizeof(*pubkey)); - return 0; - } -} - -#endif /* SECP256K1_MODULE_RECOVERY_MAIN_H */ diff --git a/Sources/secp256k1/src/num.h b/Sources/secp256k1/src/num.h deleted file mode 100644 index f8bc379..0000000 --- a/Sources/secp256k1/src/num.h +++ /dev/null @@ -1,12 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_NUM_H -#define SECP256K1_NUM_H - -#define USE_NUM_NONE - -#endif /* SECP256K1_NUM_H */ diff --git a/Sources/secp256k1/src/num_impl.h b/Sources/secp256k1/src/num_impl.h deleted file mode 100644 index f89361b..0000000 --- a/Sources/secp256k1/src/num_impl.h +++ /dev/null @@ -1,12 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_NUM_IMPL_H -#define SECP256K1_NUM_IMPL_H - -#include "num.h" - -#endif /* SECP256K1_NUM_IMPL_H */ diff --git a/Sources/secp256k1/src/scalar.h b/Sources/secp256k1/src/scalar.h deleted file mode 100644 index 9bd6f5a..0000000 --- a/Sources/secp256k1/src/scalar.h +++ /dev/null @@ -1,95 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_SCALAR_H -#define SECP256K1_SCALAR_H - -#define USE_SCALAR_INV_BUILTIN - -#include "num.h" -#include "scalar_8x32.h" - -/** Clear a scalar to prevent the leak of sensitive data. */ -static void secp256k1_scalar_clear(secp256k1_scalar *r); - -/** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */ -static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count); - -/** Access bits from a scalar. Not constant time. */ -static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count); - -/** Set a scalar from a big endian byte array. */ -static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow); - -/** Set a scalar to an unsigned integer. */ -static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v); - -/** Convert a scalar to a byte array. */ -static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a); - -/** Add two scalars together (modulo the group order). Returns whether it overflowed. */ -static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); - -/** Conditionally add a power of two to a scalar. The result is not allowed to overflow. */ -static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag); - -/** Multiply two scalars (modulo the group order). */ -static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); - -/** Shift a scalar right by some amount strictly between 0 and 16, returning - * the low bits that were shifted off */ -static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n); - -/** Compute the square of a scalar (modulo the group order). */ -static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a); - -/** Compute the inverse of a scalar (modulo the group order). */ -static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *a); - -/** Compute the inverse of a scalar (modulo the group order), without constant-time guarantee. */ -static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *a); - -/** Compute the complement of a scalar (modulo the group order). */ -static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a); - -/** Check whether a scalar equals zero. */ -static int secp256k1_scalar_is_zero(const secp256k1_scalar *a); - -/** Check whether a scalar equals one. */ -static int secp256k1_scalar_is_one(const secp256k1_scalar *a); - -/** Check whether a scalar, considered as an nonnegative integer, is even. */ -static int secp256k1_scalar_is_even(const secp256k1_scalar *a); - -/** Check whether a scalar is higher than the group order divided by 2. */ -static int secp256k1_scalar_is_high(const secp256k1_scalar *a); - -/** Conditionally negate a number, in constant time. - * Returns -1 if the number was negated, 1 otherwise */ -static int secp256k1_scalar_cond_negate(secp256k1_scalar *a, int flag); - -#ifndef USE_NUM_NONE -/** Convert a scalar to a number. */ -static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a); - -/** Get the order of the group as a number. */ -static void secp256k1_scalar_order_get_num(secp256k1_num *r); -#endif - -/** Compare two scalars. */ -static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b); - -#ifdef USE_ENDOMORPHISM -/** Find r1 and r2 such that r1+r2*2^128 = a. */ -static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); -/** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (see secp256k1_gej_mul_lambda). */ -static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); -#endif - -/** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */ -static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift); - -#endif /* SECP256K1_SCALAR_H */ diff --git a/Sources/secp256k1/src/scalar_8x32.h b/Sources/secp256k1/src/scalar_8x32.h deleted file mode 100644 index 2c9a348..0000000 --- a/Sources/secp256k1/src/scalar_8x32.h +++ /dev/null @@ -1,19 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_SCALAR_REPR_H -#define SECP256K1_SCALAR_REPR_H - -#include - -/** A scalar modulo the group order of the secp256k1 curve. */ -typedef struct { - uint32_t d[8]; -} secp256k1_scalar; - -#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)}} - -#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/Sources/secp256k1/src/scalar_8x32_impl.h b/Sources/secp256k1/src/scalar_8x32_impl.h deleted file mode 100644 index 4f9ed61..0000000 --- a/Sources/secp256k1/src/scalar_8x32_impl.h +++ /dev/null @@ -1,721 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_SCALAR_REPR_IMPL_H -#define SECP256K1_SCALAR_REPR_IMPL_H - -/* Limbs of the secp256k1 order. */ -#define SECP256K1_N_0 ((uint32_t)0xD0364141UL) -#define SECP256K1_N_1 ((uint32_t)0xBFD25E8CUL) -#define SECP256K1_N_2 ((uint32_t)0xAF48A03BUL) -#define SECP256K1_N_3 ((uint32_t)0xBAAEDCE6UL) -#define SECP256K1_N_4 ((uint32_t)0xFFFFFFFEUL) -#define SECP256K1_N_5 ((uint32_t)0xFFFFFFFFUL) -#define SECP256K1_N_6 ((uint32_t)0xFFFFFFFFUL) -#define SECP256K1_N_7 ((uint32_t)0xFFFFFFFFUL) - -/* Limbs of 2^256 minus the secp256k1 order. */ -#define SECP256K1_N_C_0 (~SECP256K1_N_0 + 1) -#define SECP256K1_N_C_1 (~SECP256K1_N_1) -#define SECP256K1_N_C_2 (~SECP256K1_N_2) -#define SECP256K1_N_C_3 (~SECP256K1_N_3) -#define SECP256K1_N_C_4 (1) - -/* Limbs of half the secp256k1 order. */ -#define SECP256K1_N_H_0 ((uint32_t)0x681B20A0UL) -#define SECP256K1_N_H_1 ((uint32_t)0xDFE92F46UL) -#define SECP256K1_N_H_2 ((uint32_t)0x57A4501DUL) -#define SECP256K1_N_H_3 ((uint32_t)0x5D576E73UL) -#define SECP256K1_N_H_4 ((uint32_t)0xFFFFFFFFUL) -#define SECP256K1_N_H_5 ((uint32_t)0xFFFFFFFFUL) -#define SECP256K1_N_H_6 ((uint32_t)0xFFFFFFFFUL) -#define SECP256K1_N_H_7 ((uint32_t)0x7FFFFFFFUL) - -SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { - r->d[0] = 0; - r->d[1] = 0; - r->d[2] = 0; - r->d[3] = 0; - r->d[4] = 0; - r->d[5] = 0; - r->d[6] = 0; - r->d[7] = 0; -} - -SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { - r->d[0] = v; - r->d[1] = 0; - r->d[2] = 0; - r->d[3] = 0; - r->d[4] = 0; - r->d[5] = 0; - r->d[6] = 0; - r->d[7] = 0; -} - -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { - VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5); - return (a->d[offset >> 5] >> (offset & 0x1F)) & ((1 << count) - 1); -} - -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { - VERIFY_CHECK(count < 32); - VERIFY_CHECK(offset + count <= 256); - if ((offset + count - 1) >> 5 == offset >> 5) { - return secp256k1_scalar_get_bits(a, offset, count); - } else { - VERIFY_CHECK((offset >> 5) + 1 < 8); - return ((a->d[offset >> 5] >> (offset & 0x1F)) | (a->d[(offset >> 5) + 1] << (32 - (offset & 0x1F)))) & ((((uint32_t)1) << count) - 1); - } -} - -SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { - int yes = 0; - int no = 0; - no |= (a->d[7] < SECP256K1_N_7); /* No need for a > check. */ - no |= (a->d[6] < SECP256K1_N_6); /* No need for a > check. */ - no |= (a->d[5] < SECP256K1_N_5); /* No need for a > check. */ - no |= (a->d[4] < SECP256K1_N_4); - yes |= (a->d[4] > SECP256K1_N_4) & ~no; - no |= (a->d[3] < SECP256K1_N_3) & ~yes; - yes |= (a->d[3] > SECP256K1_N_3) & ~no; - no |= (a->d[2] < SECP256K1_N_2) & ~yes; - yes |= (a->d[2] > SECP256K1_N_2) & ~no; - no |= (a->d[1] < SECP256K1_N_1) & ~yes; - yes |= (a->d[1] > SECP256K1_N_1) & ~no; - yes |= (a->d[0] >= SECP256K1_N_0) & ~no; - return yes; -} - -SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, uint32_t overflow) { - uint64_t t; - VERIFY_CHECK(overflow <= 1); - t = (uint64_t)r->d[0] + overflow * SECP256K1_N_C_0; - r->d[0] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[1] + overflow * SECP256K1_N_C_1; - r->d[1] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[2] + overflow * SECP256K1_N_C_2; - r->d[2] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[3] + overflow * SECP256K1_N_C_3; - r->d[3] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[4] + overflow * SECP256K1_N_C_4; - r->d[4] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[5]; - r->d[5] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[6]; - r->d[6] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[7]; - r->d[7] = t & 0xFFFFFFFFUL; - return overflow; -} - -static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { - int overflow; - uint64_t t = (uint64_t)a->d[0] + b->d[0]; - r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[1] + b->d[1]; - r->d[1] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[2] + b->d[2]; - r->d[2] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[3] + b->d[3]; - r->d[3] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[4] + b->d[4]; - r->d[4] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[5] + b->d[5]; - r->d[5] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[6] + b->d[6]; - r->d[6] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[7] + b->d[7]; - r->d[7] = t & 0xFFFFFFFFULL; t >>= 32; - overflow = t + secp256k1_scalar_check_overflow(r); - VERIFY_CHECK(overflow == 0 || overflow == 1); - secp256k1_scalar_reduce(r, overflow); - return overflow; -} - -static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { - uint64_t t; - VERIFY_CHECK(bit < 256); - bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 5) > 7 makes this a noop */ - t = (uint64_t)r->d[0] + (((uint32_t)((bit >> 5) == 0)) << (bit & 0x1F)); - r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[1] + (((uint32_t)((bit >> 5) == 1)) << (bit & 0x1F)); - r->d[1] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[2] + (((uint32_t)((bit >> 5) == 2)) << (bit & 0x1F)); - r->d[2] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[3] + (((uint32_t)((bit >> 5) == 3)) << (bit & 0x1F)); - r->d[3] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[4] + (((uint32_t)((bit >> 5) == 4)) << (bit & 0x1F)); - r->d[4] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[5] + (((uint32_t)((bit >> 5) == 5)) << (bit & 0x1F)); - r->d[5] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[6] + (((uint32_t)((bit >> 5) == 6)) << (bit & 0x1F)); - r->d[6] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[7] + (((uint32_t)((bit >> 5) == 7)) << (bit & 0x1F)); - r->d[7] = t & 0xFFFFFFFFULL; -#ifdef VERIFY - VERIFY_CHECK((t >> 32) == 0); - VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); -#endif -} - -static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { - int over; - r->d[0] = (uint32_t)b32[31] | (uint32_t)b32[30] << 8 | (uint32_t)b32[29] << 16 | (uint32_t)b32[28] << 24; - r->d[1] = (uint32_t)b32[27] | (uint32_t)b32[26] << 8 | (uint32_t)b32[25] << 16 | (uint32_t)b32[24] << 24; - r->d[2] = (uint32_t)b32[23] | (uint32_t)b32[22] << 8 | (uint32_t)b32[21] << 16 | (uint32_t)b32[20] << 24; - r->d[3] = (uint32_t)b32[19] | (uint32_t)b32[18] << 8 | (uint32_t)b32[17] << 16 | (uint32_t)b32[16] << 24; - r->d[4] = (uint32_t)b32[15] | (uint32_t)b32[14] << 8 | (uint32_t)b32[13] << 16 | (uint32_t)b32[12] << 24; - r->d[5] = (uint32_t)b32[11] | (uint32_t)b32[10] << 8 | (uint32_t)b32[9] << 16 | (uint32_t)b32[8] << 24; - r->d[6] = (uint32_t)b32[7] | (uint32_t)b32[6] << 8 | (uint32_t)b32[5] << 16 | (uint32_t)b32[4] << 24; - r->d[7] = (uint32_t)b32[3] | (uint32_t)b32[2] << 8 | (uint32_t)b32[1] << 16 | (uint32_t)b32[0] << 24; - over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); - if (overflow) { - *overflow = over; - } -} - -static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { - bin[0] = a->d[7] >> 24; bin[1] = a->d[7] >> 16; bin[2] = a->d[7] >> 8; bin[3] = a->d[7]; - bin[4] = a->d[6] >> 24; bin[5] = a->d[6] >> 16; bin[6] = a->d[6] >> 8; bin[7] = a->d[6]; - bin[8] = a->d[5] >> 24; bin[9] = a->d[5] >> 16; bin[10] = a->d[5] >> 8; bin[11] = a->d[5]; - bin[12] = a->d[4] >> 24; bin[13] = a->d[4] >> 16; bin[14] = a->d[4] >> 8; bin[15] = a->d[4]; - bin[16] = a->d[3] >> 24; bin[17] = a->d[3] >> 16; bin[18] = a->d[3] >> 8; bin[19] = a->d[3]; - bin[20] = a->d[2] >> 24; bin[21] = a->d[2] >> 16; bin[22] = a->d[2] >> 8; bin[23] = a->d[2]; - bin[24] = a->d[1] >> 24; bin[25] = a->d[1] >> 16; bin[26] = a->d[1] >> 8; bin[27] = a->d[1]; - bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0]; -} - -SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { - return (a->d[0] | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0; -} - -static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { - uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(a) == 0); - uint64_t t = (uint64_t)(~a->d[0]) + SECP256K1_N_0 + 1; - r->d[0] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[1]) + SECP256K1_N_1; - r->d[1] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[2]) + SECP256K1_N_2; - r->d[2] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[3]) + SECP256K1_N_3; - r->d[3] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[4]) + SECP256K1_N_4; - r->d[4] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[5]) + SECP256K1_N_5; - r->d[5] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[6]) + SECP256K1_N_6; - r->d[6] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[7]) + SECP256K1_N_7; - r->d[7] = t & nonzero; -} - -SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { - return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0; -} - -static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { - int yes = 0; - int no = 0; - no |= (a->d[7] < SECP256K1_N_H_7); - yes |= (a->d[7] > SECP256K1_N_H_7) & ~no; - no |= (a->d[6] < SECP256K1_N_H_6) & ~yes; /* No need for a > check. */ - no |= (a->d[5] < SECP256K1_N_H_5) & ~yes; /* No need for a > check. */ - no |= (a->d[4] < SECP256K1_N_H_4) & ~yes; /* No need for a > check. */ - no |= (a->d[3] < SECP256K1_N_H_3) & ~yes; - yes |= (a->d[3] > SECP256K1_N_H_3) & ~no; - no |= (a->d[2] < SECP256K1_N_H_2) & ~yes; - yes |= (a->d[2] > SECP256K1_N_H_2) & ~no; - no |= (a->d[1] < SECP256K1_N_H_1) & ~yes; - yes |= (a->d[1] > SECP256K1_N_H_1) & ~no; - yes |= (a->d[0] > SECP256K1_N_H_0) & ~no; - return yes; -} - -static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { - /* If we are flag = 0, mask = 00...00 and this is a no-op; - * if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */ - uint32_t mask = !flag - 1; - uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(r) == 0); - uint64_t t = (uint64_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask); - r->d[0] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask); - r->d[1] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[2] ^ mask) + (SECP256K1_N_2 & mask); - r->d[2] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[3] ^ mask) + (SECP256K1_N_3 & mask); - r->d[3] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[4] ^ mask) + (SECP256K1_N_4 & mask); - r->d[4] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[5] ^ mask) + (SECP256K1_N_5 & mask); - r->d[5] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[6] ^ mask) + (SECP256K1_N_6 & mask); - r->d[6] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[7] ^ mask) + (SECP256K1_N_7 & mask); - r->d[7] = t & nonzero; - return 2 * (mask == 0) - 1; -} - - -/* Inspired by the macros in OpenSSL's crypto/bn/asm/x86_64-gcc.c. */ - -/** Add a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ -#define muladd(a,b) { \ - uint32_t tl, th; \ - { \ - uint64_t t = (uint64_t)a * b; \ - th = t >> 32; /* at most 0xFFFFFFFE */ \ - tl = t; \ - } \ - c0 += tl; /* overflow is handled on the next line */ \ - th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ - c1 += th; /* overflow is handled on the next line */ \ - c2 += (c1 < th) ? 1 : 0; /* never overflows by contract (verified in the next line) */ \ - VERIFY_CHECK((c1 >= th) || (c2 != 0)); \ -} - -/** Add a*b to the number defined by (c0,c1). c1 must never overflow. */ -#define muladd_fast(a,b) { \ - uint32_t tl, th; \ - { \ - uint64_t t = (uint64_t)a * b; \ - th = t >> 32; /* at most 0xFFFFFFFE */ \ - tl = t; \ - } \ - c0 += tl; /* overflow is handled on the next line */ \ - th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ - c1 += th; /* never overflows by contract (verified in the next line) */ \ - VERIFY_CHECK(c1 >= th); \ -} - -/** Add 2*a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ -#define muladd2(a,b) { \ - uint32_t tl, th, th2, tl2; \ - { \ - uint64_t t = (uint64_t)a * b; \ - th = t >> 32; /* at most 0xFFFFFFFE */ \ - tl = t; \ - } \ - th2 = th + th; /* at most 0xFFFFFFFE (in case th was 0x7FFFFFFF) */ \ - c2 += (th2 < th) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((th2 >= th) || (c2 != 0)); \ - tl2 = tl + tl; /* at most 0xFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFF) */ \ - th2 += (tl2 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ - c0 += tl2; /* overflow is handled on the next line */ \ - th2 += (c0 < tl2) ? 1 : 0; /* second overflow is handled on the next line */ \ - c2 += (c0 < tl2) & (th2 == 0); /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c0 >= tl2) || (th2 != 0) || (c2 != 0)); \ - c1 += th2; /* overflow is handled on the next line */ \ - c2 += (c1 < th2) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c1 >= th2) || (c2 != 0)); \ -} - -/** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */ -#define sumadd(a) { \ - unsigned int over; \ - c0 += (a); /* overflow is handled on the next line */ \ - over = (c0 < (a)) ? 1 : 0; \ - c1 += over; /* overflow is handled on the next line */ \ - c2 += (c1 < over) ? 1 : 0; /* never overflows by contract */ \ -} - -/** Add a to the number defined by (c0,c1). c1 must never overflow, c2 must be zero. */ -#define sumadd_fast(a) { \ - c0 += (a); /* overflow is handled on the next line */ \ - c1 += (c0 < (a)) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c1 != 0) | (c0 >= (a))); \ - VERIFY_CHECK(c2 == 0); \ -} - -/** Extract the lowest 32 bits of (c0,c1,c2) into n, and left shift the number 32 bits. */ -#define extract(n) { \ - (n) = c0; \ - c0 = c1; \ - c1 = c2; \ - c2 = 0; \ -} - -/** Extract the lowest 32 bits of (c0,c1,c2) into n, and left shift the number 32 bits. c2 is required to be zero. */ -#define extract_fast(n) { \ - (n) = c0; \ - c0 = c1; \ - c1 = 0; \ - VERIFY_CHECK(c2 == 0); \ -} - -static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint32_t *l) { - uint64_t c; - uint32_t n0 = l[8], n1 = l[9], n2 = l[10], n3 = l[11], n4 = l[12], n5 = l[13], n6 = l[14], n7 = l[15]; - uint32_t m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12; - uint32_t p0, p1, p2, p3, p4, p5, p6, p7, p8; - - /* 96 bit accumulator. */ - uint32_t c0, c1, c2; - - /* Reduce 512 bits into 385. */ - /* m[0..12] = l[0..7] + n[0..7] * SECP256K1_N_C. */ - c0 = l[0]; c1 = 0; c2 = 0; - muladd_fast(n0, SECP256K1_N_C_0); - extract_fast(m0); - sumadd_fast(l[1]); - muladd(n1, SECP256K1_N_C_0); - muladd(n0, SECP256K1_N_C_1); - extract(m1); - sumadd(l[2]); - muladd(n2, SECP256K1_N_C_0); - muladd(n1, SECP256K1_N_C_1); - muladd(n0, SECP256K1_N_C_2); - extract(m2); - sumadd(l[3]); - muladd(n3, SECP256K1_N_C_0); - muladd(n2, SECP256K1_N_C_1); - muladd(n1, SECP256K1_N_C_2); - muladd(n0, SECP256K1_N_C_3); - extract(m3); - sumadd(l[4]); - muladd(n4, SECP256K1_N_C_0); - muladd(n3, SECP256K1_N_C_1); - muladd(n2, SECP256K1_N_C_2); - muladd(n1, SECP256K1_N_C_3); - sumadd(n0); - extract(m4); - sumadd(l[5]); - muladd(n5, SECP256K1_N_C_0); - muladd(n4, SECP256K1_N_C_1); - muladd(n3, SECP256K1_N_C_2); - muladd(n2, SECP256K1_N_C_3); - sumadd(n1); - extract(m5); - sumadd(l[6]); - muladd(n6, SECP256K1_N_C_0); - muladd(n5, SECP256K1_N_C_1); - muladd(n4, SECP256K1_N_C_2); - muladd(n3, SECP256K1_N_C_3); - sumadd(n2); - extract(m6); - sumadd(l[7]); - muladd(n7, SECP256K1_N_C_0); - muladd(n6, SECP256K1_N_C_1); - muladd(n5, SECP256K1_N_C_2); - muladd(n4, SECP256K1_N_C_3); - sumadd(n3); - extract(m7); - muladd(n7, SECP256K1_N_C_1); - muladd(n6, SECP256K1_N_C_2); - muladd(n5, SECP256K1_N_C_3); - sumadd(n4); - extract(m8); - muladd(n7, SECP256K1_N_C_2); - muladd(n6, SECP256K1_N_C_3); - sumadd(n5); - extract(m9); - muladd(n7, SECP256K1_N_C_3); - sumadd(n6); - extract(m10); - sumadd_fast(n7); - extract_fast(m11); - VERIFY_CHECK(c0 <= 1); - m12 = c0; - - /* Reduce 385 bits into 258. */ - /* p[0..8] = m[0..7] + m[8..12] * SECP256K1_N_C. */ - c0 = m0; c1 = 0; c2 = 0; - muladd_fast(m8, SECP256K1_N_C_0); - extract_fast(p0); - sumadd_fast(m1); - muladd(m9, SECP256K1_N_C_0); - muladd(m8, SECP256K1_N_C_1); - extract(p1); - sumadd(m2); - muladd(m10, SECP256K1_N_C_0); - muladd(m9, SECP256K1_N_C_1); - muladd(m8, SECP256K1_N_C_2); - extract(p2); - sumadd(m3); - muladd(m11, SECP256K1_N_C_0); - muladd(m10, SECP256K1_N_C_1); - muladd(m9, SECP256K1_N_C_2); - muladd(m8, SECP256K1_N_C_3); - extract(p3); - sumadd(m4); - muladd(m12, SECP256K1_N_C_0); - muladd(m11, SECP256K1_N_C_1); - muladd(m10, SECP256K1_N_C_2); - muladd(m9, SECP256K1_N_C_3); - sumadd(m8); - extract(p4); - sumadd(m5); - muladd(m12, SECP256K1_N_C_1); - muladd(m11, SECP256K1_N_C_2); - muladd(m10, SECP256K1_N_C_3); - sumadd(m9); - extract(p5); - sumadd(m6); - muladd(m12, SECP256K1_N_C_2); - muladd(m11, SECP256K1_N_C_3); - sumadd(m10); - extract(p6); - sumadd_fast(m7); - muladd_fast(m12, SECP256K1_N_C_3); - sumadd_fast(m11); - extract_fast(p7); - p8 = c0 + m12; - VERIFY_CHECK(p8 <= 2); - - /* Reduce 258 bits into 256. */ - /* r[0..7] = p[0..7] + p[8] * SECP256K1_N_C. */ - c = p0 + (uint64_t)SECP256K1_N_C_0 * p8; - r->d[0] = c & 0xFFFFFFFFUL; c >>= 32; - c += p1 + (uint64_t)SECP256K1_N_C_1 * p8; - r->d[1] = c & 0xFFFFFFFFUL; c >>= 32; - c += p2 + (uint64_t)SECP256K1_N_C_2 * p8; - r->d[2] = c & 0xFFFFFFFFUL; c >>= 32; - c += p3 + (uint64_t)SECP256K1_N_C_3 * p8; - r->d[3] = c & 0xFFFFFFFFUL; c >>= 32; - c += p4 + (uint64_t)p8; - r->d[4] = c & 0xFFFFFFFFUL; c >>= 32; - c += p5; - r->d[5] = c & 0xFFFFFFFFUL; c >>= 32; - c += p6; - r->d[6] = c & 0xFFFFFFFFUL; c >>= 32; - c += p7; - r->d[7] = c & 0xFFFFFFFFUL; c >>= 32; - - /* Final reduction of r. */ - secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); -} - -static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar *a, const secp256k1_scalar *b) { - /* 96 bit accumulator. */ - uint32_t c0 = 0, c1 = 0, c2 = 0; - - /* l[0..15] = a[0..7] * b[0..7]. */ - muladd_fast(a->d[0], b->d[0]); - extract_fast(l[0]); - muladd(a->d[0], b->d[1]); - muladd(a->d[1], b->d[0]); - extract(l[1]); - muladd(a->d[0], b->d[2]); - muladd(a->d[1], b->d[1]); - muladd(a->d[2], b->d[0]); - extract(l[2]); - muladd(a->d[0], b->d[3]); - muladd(a->d[1], b->d[2]); - muladd(a->d[2], b->d[1]); - muladd(a->d[3], b->d[0]); - extract(l[3]); - muladd(a->d[0], b->d[4]); - muladd(a->d[1], b->d[3]); - muladd(a->d[2], b->d[2]); - muladd(a->d[3], b->d[1]); - muladd(a->d[4], b->d[0]); - extract(l[4]); - muladd(a->d[0], b->d[5]); - muladd(a->d[1], b->d[4]); - muladd(a->d[2], b->d[3]); - muladd(a->d[3], b->d[2]); - muladd(a->d[4], b->d[1]); - muladd(a->d[5], b->d[0]); - extract(l[5]); - muladd(a->d[0], b->d[6]); - muladd(a->d[1], b->d[5]); - muladd(a->d[2], b->d[4]); - muladd(a->d[3], b->d[3]); - muladd(a->d[4], b->d[2]); - muladd(a->d[5], b->d[1]); - muladd(a->d[6], b->d[0]); - extract(l[6]); - muladd(a->d[0], b->d[7]); - muladd(a->d[1], b->d[6]); - muladd(a->d[2], b->d[5]); - muladd(a->d[3], b->d[4]); - muladd(a->d[4], b->d[3]); - muladd(a->d[5], b->d[2]); - muladd(a->d[6], b->d[1]); - muladd(a->d[7], b->d[0]); - extract(l[7]); - muladd(a->d[1], b->d[7]); - muladd(a->d[2], b->d[6]); - muladd(a->d[3], b->d[5]); - muladd(a->d[4], b->d[4]); - muladd(a->d[5], b->d[3]); - muladd(a->d[6], b->d[2]); - muladd(a->d[7], b->d[1]); - extract(l[8]); - muladd(a->d[2], b->d[7]); - muladd(a->d[3], b->d[6]); - muladd(a->d[4], b->d[5]); - muladd(a->d[5], b->d[4]); - muladd(a->d[6], b->d[3]); - muladd(a->d[7], b->d[2]); - extract(l[9]); - muladd(a->d[3], b->d[7]); - muladd(a->d[4], b->d[6]); - muladd(a->d[5], b->d[5]); - muladd(a->d[6], b->d[4]); - muladd(a->d[7], b->d[3]); - extract(l[10]); - muladd(a->d[4], b->d[7]); - muladd(a->d[5], b->d[6]); - muladd(a->d[6], b->d[5]); - muladd(a->d[7], b->d[4]); - extract(l[11]); - muladd(a->d[5], b->d[7]); - muladd(a->d[6], b->d[6]); - muladd(a->d[7], b->d[5]); - extract(l[12]); - muladd(a->d[6], b->d[7]); - muladd(a->d[7], b->d[6]); - extract(l[13]); - muladd_fast(a->d[7], b->d[7]); - extract_fast(l[14]); - VERIFY_CHECK(c1 == 0); - l[15] = c0; -} - -static void secp256k1_scalar_sqr_512(uint32_t *l, const secp256k1_scalar *a) { - /* 96 bit accumulator. */ - uint32_t c0 = 0, c1 = 0, c2 = 0; - - /* l[0..15] = a[0..7]^2. */ - muladd_fast(a->d[0], a->d[0]); - extract_fast(l[0]); - muladd2(a->d[0], a->d[1]); - extract(l[1]); - muladd2(a->d[0], a->d[2]); - muladd(a->d[1], a->d[1]); - extract(l[2]); - muladd2(a->d[0], a->d[3]); - muladd2(a->d[1], a->d[2]); - extract(l[3]); - muladd2(a->d[0], a->d[4]); - muladd2(a->d[1], a->d[3]); - muladd(a->d[2], a->d[2]); - extract(l[4]); - muladd2(a->d[0], a->d[5]); - muladd2(a->d[1], a->d[4]); - muladd2(a->d[2], a->d[3]); - extract(l[5]); - muladd2(a->d[0], a->d[6]); - muladd2(a->d[1], a->d[5]); - muladd2(a->d[2], a->d[4]); - muladd(a->d[3], a->d[3]); - extract(l[6]); - muladd2(a->d[0], a->d[7]); - muladd2(a->d[1], a->d[6]); - muladd2(a->d[2], a->d[5]); - muladd2(a->d[3], a->d[4]); - extract(l[7]); - muladd2(a->d[1], a->d[7]); - muladd2(a->d[2], a->d[6]); - muladd2(a->d[3], a->d[5]); - muladd(a->d[4], a->d[4]); - extract(l[8]); - muladd2(a->d[2], a->d[7]); - muladd2(a->d[3], a->d[6]); - muladd2(a->d[4], a->d[5]); - extract(l[9]); - muladd2(a->d[3], a->d[7]); - muladd2(a->d[4], a->d[6]); - muladd(a->d[5], a->d[5]); - extract(l[10]); - muladd2(a->d[4], a->d[7]); - muladd2(a->d[5], a->d[6]); - extract(l[11]); - muladd2(a->d[5], a->d[7]); - muladd(a->d[6], a->d[6]); - extract(l[12]); - muladd2(a->d[6], a->d[7]); - extract(l[13]); - muladd_fast(a->d[7], a->d[7]); - extract_fast(l[14]); - VERIFY_CHECK(c1 == 0); - l[15] = c0; -} - -#undef sumadd -#undef sumadd_fast -#undef muladd -#undef muladd_fast -#undef muladd2 -#undef extract -#undef extract_fast - -static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { - uint32_t l[16]; - secp256k1_scalar_mul_512(l, a, b); - secp256k1_scalar_reduce_512(r, l); -} - -static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { - int ret; - VERIFY_CHECK(n > 0); - VERIFY_CHECK(n < 16); - ret = r->d[0] & ((1 << n) - 1); - r->d[0] = (r->d[0] >> n) + (r->d[1] << (32 - n)); - r->d[1] = (r->d[1] >> n) + (r->d[2] << (32 - n)); - r->d[2] = (r->d[2] >> n) + (r->d[3] << (32 - n)); - r->d[3] = (r->d[3] >> n) + (r->d[4] << (32 - n)); - r->d[4] = (r->d[4] >> n) + (r->d[5] << (32 - n)); - r->d[5] = (r->d[5] >> n) + (r->d[6] << (32 - n)); - r->d[6] = (r->d[6] >> n) + (r->d[7] << (32 - n)); - r->d[7] = (r->d[7] >> n); - return ret; -} - -static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { - uint32_t l[16]; - secp256k1_scalar_sqr_512(l, a); - secp256k1_scalar_reduce_512(r, l); -} - -#ifdef USE_ENDOMORPHISM -static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { - r1->d[0] = a->d[0]; - r1->d[1] = a->d[1]; - r1->d[2] = a->d[2]; - r1->d[3] = a->d[3]; - r1->d[4] = 0; - r1->d[5] = 0; - r1->d[6] = 0; - r1->d[7] = 0; - r2->d[0] = a->d[4]; - r2->d[1] = a->d[5]; - r2->d[2] = a->d[6]; - r2->d[3] = a->d[7]; - r2->d[4] = 0; - r2->d[5] = 0; - r2->d[6] = 0; - r2->d[7] = 0; -} -#endif - -SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { - return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3]) | (a->d[4] ^ b->d[4]) | (a->d[5] ^ b->d[5]) | (a->d[6] ^ b->d[6]) | (a->d[7] ^ b->d[7])) == 0; -} - -SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift) { - uint32_t l[16]; - unsigned int shiftlimbs; - unsigned int shiftlow; - unsigned int shifthigh; - VERIFY_CHECK(shift >= 256); - secp256k1_scalar_mul_512(l, a, b); - shiftlimbs = shift >> 5; - shiftlow = shift & 0x1F; - shifthigh = 32 - shiftlow; - r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 480 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[1] = shift < 480 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[2] = shift < 448 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 416 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[3] = shift < 416 ? (l[3 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[4 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[4] = shift < 384 ? (l[4 + shiftlimbs] >> shiftlow | (shift < 352 && shiftlow ? (l[5 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[5] = shift < 352 ? (l[5 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[6 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[6] = shift < 320 ? (l[6 + shiftlimbs] >> shiftlow | (shift < 288 && shiftlow ? (l[7 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[7] = shift < 288 ? (l[7 + shiftlimbs] >> shiftlow) : 0; - secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 5] >> ((shift - 1) & 0x1f)) & 1); -} - -#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/Sources/secp256k1/src/scalar_impl.h b/Sources/secp256k1/src/scalar_impl.h deleted file mode 100644 index 715ef7f..0000000 --- a/Sources/secp256k1/src/scalar_impl.h +++ /dev/null @@ -1,320 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_SCALAR_IMPL_H -#define SECP256K1_SCALAR_IMPL_H - -#include "group.h" -#include "scalar.h" -#include "scalar_8x32_impl.h" - -#ifndef USE_NUM_NONE -static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a) { - unsigned char c[32]; - secp256k1_scalar_get_b32(c, a); - secp256k1_num_set_bin(r, c, 32); -} - -/** secp256k1 curve order, see secp256k1_ecdsa_const_order_as_fe in ecdsa_impl.h */ -static void secp256k1_scalar_order_get_num(secp256k1_num *r) { -#if defined(EXHAUSTIVE_TEST_ORDER) - static const unsigned char order[32] = { - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,EXHAUSTIVE_TEST_ORDER - }; -#else - static const unsigned char order[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, - 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 - }; -#endif - secp256k1_num_set_bin(r, order, 32); -} -#endif - -static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { -#if defined(EXHAUSTIVE_TEST_ORDER) - int i; - *r = 0; - for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) - if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1) - *r = i; - /* If this VERIFY_CHECK triggers we were given a noninvertible scalar (and thus - * have a composite group order; fix it in exhaustive_tests.c). */ - VERIFY_CHECK(*r != 0); -} -#else - secp256k1_scalar *t; - int i; - /* First compute xN as x ^ (2^N - 1) for some values of N, - * and uM as x ^ M for some values of M. */ - secp256k1_scalar x2, x3, x6, x8, x14, x28, x56, x112, x126; - secp256k1_scalar u2, u5, u9, u11, u13; - - secp256k1_scalar_sqr(&u2, x); - secp256k1_scalar_mul(&x2, &u2, x); - secp256k1_scalar_mul(&u5, &u2, &x2); - secp256k1_scalar_mul(&x3, &u5, &u2); - secp256k1_scalar_mul(&u9, &x3, &u2); - secp256k1_scalar_mul(&u11, &u9, &u2); - secp256k1_scalar_mul(&u13, &u11, &u2); - - secp256k1_scalar_sqr(&x6, &u13); - secp256k1_scalar_sqr(&x6, &x6); - secp256k1_scalar_mul(&x6, &x6, &u11); - - secp256k1_scalar_sqr(&x8, &x6); - secp256k1_scalar_sqr(&x8, &x8); - secp256k1_scalar_mul(&x8, &x8, &x2); - - secp256k1_scalar_sqr(&x14, &x8); - for (i = 0; i < 5; i++) { - secp256k1_scalar_sqr(&x14, &x14); - } - secp256k1_scalar_mul(&x14, &x14, &x6); - - secp256k1_scalar_sqr(&x28, &x14); - for (i = 0; i < 13; i++) { - secp256k1_scalar_sqr(&x28, &x28); - } - secp256k1_scalar_mul(&x28, &x28, &x14); - - secp256k1_scalar_sqr(&x56, &x28); - for (i = 0; i < 27; i++) { - secp256k1_scalar_sqr(&x56, &x56); - } - secp256k1_scalar_mul(&x56, &x56, &x28); - - secp256k1_scalar_sqr(&x112, &x56); - for (i = 0; i < 55; i++) { - secp256k1_scalar_sqr(&x112, &x112); - } - secp256k1_scalar_mul(&x112, &x112, &x56); - - secp256k1_scalar_sqr(&x126, &x112); - for (i = 0; i < 13; i++) { - secp256k1_scalar_sqr(&x126, &x126); - } - secp256k1_scalar_mul(&x126, &x126, &x14); - - /* Then accumulate the final result (t starts at x126). */ - t = &x126; - for (i = 0; i < 3; i++) { - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u5); /* 101 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u5); /* 101 */ - for (i = 0; i < 5; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u11); /* 1011 */ - for (i = 0; i < 4; i++) { - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u11); /* 1011 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 5; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 6; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u13); /* 1101 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u5); /* 101 */ - for (i = 0; i < 3; i++) { - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 5; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u9); /* 1001 */ - for (i = 0; i < 6; i++) { /* 000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u5); /* 101 */ - for (i = 0; i < 10; i++) { /* 0000000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 9; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x8); /* 11111111 */ - for (i = 0; i < 5; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u9); /* 1001 */ - for (i = 0; i < 6; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u11); /* 1011 */ - for (i = 0; i < 4; i++) { - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u13); /* 1101 */ - for (i = 0; i < 5; i++) { - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 6; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u13); /* 1101 */ - for (i = 0; i < 10; i++) { /* 000000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u13); /* 1101 */ - for (i = 0; i < 4; i++) { - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u9); /* 1001 */ - for (i = 0; i < 6; i++) { /* 00000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 8; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(r, t, &x6); /* 111111 */ -} - -SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { - return !(a->d[0] & 1); -} -#endif - -static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { -#if defined(USE_SCALAR_INV_BUILTIN) - secp256k1_scalar_inverse(r, x); -#elif defined(USE_SCALAR_INV_NUM) - unsigned char b[32]; - secp256k1_num n, m; - secp256k1_scalar t = *x; - secp256k1_scalar_get_b32(b, &t); - secp256k1_num_set_bin(&n, b, 32); - secp256k1_scalar_order_get_num(&m); - secp256k1_num_mod_inverse(&n, &n, &m); - secp256k1_num_get_bin(b, 32, &n); - secp256k1_scalar_set_b32(r, b, NULL); - /* Verify that the inverse was computed correctly, without GMP code. */ - secp256k1_scalar_mul(&t, &t, r); - CHECK(secp256k1_scalar_is_one(&t)); -#else -#error "Please select scalar inverse implementation" -#endif -} - -#ifdef USE_ENDOMORPHISM -#if defined(EXHAUSTIVE_TEST_ORDER) -/** - * Find k1 and k2 given k, such that k1 + k2 * lambda == k mod n; unlike in the - * full case we don't bother making k1 and k2 be small, we just want them to be - * nontrivial to get full test coverage for the exhaustive tests. We therefore - * (arbitrarily) set k2 = k + 5 and k1 = k - k2 * lambda. - */ -static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { - *r2 = (*a + 5) % EXHAUSTIVE_TEST_ORDER; - *r1 = (*a + (EXHAUSTIVE_TEST_ORDER - *r2) * EXHAUSTIVE_TEST_LAMBDA) % EXHAUSTIVE_TEST_ORDER; -} -#else -/** - * The Secp256k1 curve has an endomorphism, where lambda * (x, y) = (beta * x, y), where - * lambda is {0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a, - * 0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78,0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72} - * - * "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm - * (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1 - * and k2 have a small size. - * It relies on constants a1, b1, a2, b2. These constants for the value of lambda above are: - * - * - a1 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} - * - b1 = -{0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3} - * - a2 = {0x01,0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8} - * - b2 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} - * - * The algorithm then computes c1 = round(b1 * k / n) and c2 = round(b2 * k / n), and gives - * k1 = k - (c1*a1 + c2*a2) and k2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and - * compute k1 as k - k2 * lambda, avoiding the need for constants a1 and a2. - * - * g1, g2 are precomputed constants used to replace division with a rounded multiplication - * when decomposing the scalar for an endomorphism-based point multiplication. - * - * The possibility of using precomputed estimates is mentioned in "Guide to Elliptic Curve - * Cryptography" (Hankerson, Menezes, Vanstone) in section 3.5. - * - * The derivation is described in the paper "Efficient Software Implementation of Public-Key - * Cryptography on Sensor Networks Using the MSP430X Microcontroller" (Gouvea, Oliveira, Lopez), - * Section 4.3 (here we use a somewhat higher-precision estimate): - * d = a1*b2 - b1*a2 - * g1 = round((2^272)*b2/d) - * g2 = round((2^272)*b1/d) - * - * (Note that 'd' is also equal to the curve order here because [a1,b1] and [a2,b2] are found - * as outputs of the Extended Euclidean Algorithm on inputs 'order' and 'lambda'). - * - * The function below splits a in r1 and r2, such that r1 + lambda * r2 == a (mod order). - */ - -static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { - secp256k1_scalar c1, c2; - static const secp256k1_scalar minus_lambda = SECP256K1_SCALAR_CONST( - 0xAC9C52B3UL, 0x3FA3CF1FUL, 0x5AD9E3FDUL, 0x77ED9BA4UL, - 0xA880B9FCUL, 0x8EC739C2UL, 0xE0CFC810UL, 0xB51283CFUL - ); - static const secp256k1_scalar minus_b1 = SECP256K1_SCALAR_CONST( - 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, - 0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C3UL - ); - static const secp256k1_scalar minus_b2 = SECP256K1_SCALAR_CONST( - 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, - 0x8A280AC5UL, 0x0774346DUL, 0xD765CDA8UL, 0x3DB1562CUL - ); - static const secp256k1_scalar g1 = SECP256K1_SCALAR_CONST( - 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00003086UL, - 0xD221A7D4UL, 0x6BCDE86CUL, 0x90E49284UL, 0xEB153DABUL - ); - static const secp256k1_scalar g2 = SECP256K1_SCALAR_CONST( - 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x0000E443UL, - 0x7ED6010EUL, 0x88286F54UL, 0x7FA90ABFUL, 0xE4C42212UL - ); - VERIFY_CHECK(r1 != a); - VERIFY_CHECK(r2 != a); - /* these _var calls are constant time since the shift amount is constant */ - secp256k1_scalar_mul_shift_var(&c1, a, &g1, 272); - secp256k1_scalar_mul_shift_var(&c2, a, &g2, 272); - secp256k1_scalar_mul(&c1, &c1, &minus_b1); - secp256k1_scalar_mul(&c2, &c2, &minus_b2); - secp256k1_scalar_add(r2, &c1, &c2); - secp256k1_scalar_mul(r1, r2, &minus_lambda); - secp256k1_scalar_add(r1, r1, a); -} -#endif -#endif - -#endif /* SECP256K1_SCALAR_IMPL_H */ diff --git a/Sources/secp256k1/src/scratch.h b/Sources/secp256k1/src/scratch.h deleted file mode 100644 index fef377a..0000000 --- a/Sources/secp256k1/src/scratch.h +++ /dev/null @@ -1,39 +0,0 @@ -/********************************************************************** - * Copyright (c) 2017 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef _SECP256K1_SCRATCH_ -#define _SECP256K1_SCRATCH_ - -#define SECP256K1_SCRATCH_MAX_FRAMES 5 - -/* The typedef is used internally; the struct name is used in the public API - * (where it is exposed as a different typedef) */ -typedef struct secp256k1_scratch_space_struct { - void *data[SECP256K1_SCRATCH_MAX_FRAMES]; - size_t offset[SECP256K1_SCRATCH_MAX_FRAMES]; - size_t frame_size[SECP256K1_SCRATCH_MAX_FRAMES]; - size_t frame; - size_t max_size; - const secp256k1_callback* error_callback; -} secp256k1_scratch; - -static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size); - -static void secp256k1_scratch_destroy(secp256k1_scratch* scratch); - -/** Attempts to allocate a new stack frame with `n` available bytes. Returns 1 on success, 0 on failure */ -static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects); - -/** Deallocates a stack frame */ -static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch); - -/** Returns the maximum allocation the scratch space will allow */ -static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t n_objects); - -/** Returns a pointer into the most recently allocated frame, or NULL if there is insufficient available space */ -static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t n); - -#endif diff --git a/Sources/secp256k1/src/scratch_impl.h b/Sources/secp256k1/src/scratch_impl.h deleted file mode 100644 index abed713..0000000 --- a/Sources/secp256k1/src/scratch_impl.h +++ /dev/null @@ -1,86 +0,0 @@ -/********************************************************************** - * Copyright (c) 2017 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef _SECP256K1_SCRATCH_IMPL_H_ -#define _SECP256K1_SCRATCH_IMPL_H_ - -#include "scratch.h" - -/* Using 16 bytes alignment because common architectures never have alignment - * requirements above 8 for any of the types we care about. In addition we - * leave some room because currently we don't care about a few bytes. - * TODO: Determine this at configure time. */ -#define ALIGNMENT 16 - -static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size) { - secp256k1_scratch* ret = (secp256k1_scratch*)checked_malloc(error_callback, sizeof(*ret)); - if (ret != NULL) { - memset(ret, 0, sizeof(*ret)); - ret->max_size = max_size; - ret->error_callback = error_callback; - } - return ret; -} - -static void secp256k1_scratch_destroy(secp256k1_scratch* scratch) { - if (scratch != NULL) { - VERIFY_CHECK(scratch->frame == 0); - free(scratch); - } -} - -static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t objects) { - size_t i = 0; - size_t allocated = 0; - for (i = 0; i < scratch->frame; i++) { - allocated += scratch->frame_size[i]; - } - if (scratch->max_size - allocated <= objects * ALIGNMENT) { - return 0; - } - return scratch->max_size - allocated - objects * ALIGNMENT; -} - -static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects) { - VERIFY_CHECK(scratch->frame < SECP256K1_SCRATCH_MAX_FRAMES); - - if (n <= secp256k1_scratch_max_allocation(scratch, objects)) { - n += objects * ALIGNMENT; - scratch->data[scratch->frame] = checked_malloc(scratch->error_callback, n); - if (scratch->data[scratch->frame] == NULL) { - return 0; - } - scratch->frame_size[scratch->frame] = n; - scratch->offset[scratch->frame] = 0; - scratch->frame++; - return 1; - } else { - return 0; - } -} - -static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch) { - VERIFY_CHECK(scratch->frame > 0); - scratch->frame -= 1; - free(scratch->data[scratch->frame]); -} - -static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t size) { - void *ret; - size_t frame = scratch->frame - 1; - size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT; - - if (scratch->frame == 0 || size + scratch->offset[frame] > scratch->frame_size[frame]) { - return NULL; - } - ret = (void *) ((unsigned char *) scratch->data[frame] + scratch->offset[frame]); - memset(ret, 0, size); - scratch->offset[frame] += size; - - return ret; -} - -#endif diff --git a/Sources/secp256k1/src/secp256k1.c b/Sources/secp256k1/src/secp256k1.c deleted file mode 100644 index c7c5150..0000000 --- a/Sources/secp256k1/src/secp256k1.c +++ /dev/null @@ -1,592 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#include "secp256k1.h" - -#include "util.h" -#include "num_impl.h" -#include "field_impl.h" -#include "scalar_impl.h" -#include "group_impl.h" -#include "ecmult_impl.h" -#include "ecmult_const_impl.h" -#include "ecmult_gen_impl.h" -#include "ecdsa_impl.h" -#include "eckey_impl.h" -#include "hash_impl.h" -#include "scratch_impl.h" - -#define ARG_CHECK(cond) do { \ - if (EXPECT(!(cond), 0)) { \ - secp256k1_callback_call(&ctx->illegal_callback, #cond); \ - return 0; \ - } \ -} while(0) - -static void default_illegal_callback_fn(const char* str, void* data) { - (void)data; - fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); - abort(); -} - -static const secp256k1_callback default_illegal_callback = { - default_illegal_callback_fn, - NULL -}; - -static void default_error_callback_fn(const char* str, void* data) { - (void)data; - fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); - abort(); -} - -static const secp256k1_callback default_error_callback = { - default_error_callback_fn, - NULL -}; - - -struct secp256k1_context_struct { - secp256k1_ecmult_context ecmult_ctx; - secp256k1_ecmult_gen_context ecmult_gen_ctx; - secp256k1_callback illegal_callback; - secp256k1_callback error_callback; -}; - -secp256k1_context* secp256k1_context_create(unsigned int flags) { - secp256k1_context* ret = (secp256k1_context*)checked_malloc(&default_error_callback, sizeof(secp256k1_context)); - ret->illegal_callback = default_illegal_callback; - ret->error_callback = default_error_callback; - - if (EXPECT((flags & SECP256K1_FLAGS_TYPE_MASK) != SECP256K1_FLAGS_TYPE_CONTEXT, 0)) { - secp256k1_callback_call(&ret->illegal_callback, - "Invalid flags"); - free(ret); - return NULL; - } - - secp256k1_ecmult_context_init(&ret->ecmult_ctx); - secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx); - - if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) { - secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &ret->error_callback); - } - if (flags & SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) { - secp256k1_ecmult_context_build(&ret->ecmult_ctx, &ret->error_callback); - } - - return ret; -} - -secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { - secp256k1_context* ret = (secp256k1_context*)checked_malloc(&ctx->error_callback, sizeof(secp256k1_context)); - ret->illegal_callback = ctx->illegal_callback; - ret->error_callback = ctx->error_callback; - secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx, &ctx->error_callback); - secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx, &ctx->error_callback); - return ret; -} - -void secp256k1_context_destroy(secp256k1_context* ctx) { - if (ctx != NULL) { - secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); - secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); - - free(ctx); - } -} - -void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { - if (fun == NULL) { - fun = default_illegal_callback_fn; - } - ctx->illegal_callback.fn = fun; - ctx->illegal_callback.data = data; -} - -void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { - if (fun == NULL) { - fun = default_error_callback_fn; - } - ctx->error_callback.fn = fun; - ctx->error_callback.data = data; -} - -secp256k1_scratch_space* secp256k1_scratch_space_create(const secp256k1_context* ctx, size_t max_size) { - VERIFY_CHECK(ctx != NULL); - return secp256k1_scratch_create(&ctx->error_callback, max_size); -} - -void secp256k1_scratch_space_destroy(secp256k1_scratch_space* scratch) { - secp256k1_scratch_destroy(scratch); -} - -static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) { - if (sizeof(secp256k1_ge_storage) == 64) { - /* When the secp256k1_ge_storage type is exactly 64 byte, use its - * representation inside secp256k1_pubkey, as conversion is very fast. - * Note that secp256k1_pubkey_save must use the same representation. */ - secp256k1_ge_storage s; - memcpy(&s, &pubkey->data[0], sizeof(s)); - secp256k1_ge_from_storage(ge, &s); - } else { - /* Otherwise, fall back to 32-byte big endian for X and Y. */ - secp256k1_fe x, y; - secp256k1_fe_set_b32(&x, pubkey->data); - secp256k1_fe_set_b32(&y, pubkey->data + 32); - secp256k1_ge_set_xy(ge, &x, &y); - } - ARG_CHECK(!secp256k1_fe_is_zero(&ge->x)); - return 1; -} - -static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { - if (sizeof(secp256k1_ge_storage) == 64) { - secp256k1_ge_storage s; - secp256k1_ge_to_storage(&s, ge); - memcpy(&pubkey->data[0], &s, sizeof(s)); - } else { - VERIFY_CHECK(!secp256k1_ge_is_infinity(ge)); - secp256k1_fe_normalize_var(&ge->x); - secp256k1_fe_normalize_var(&ge->y); - secp256k1_fe_get_b32(pubkey->data, &ge->x); - secp256k1_fe_get_b32(pubkey->data + 32, &ge->y); - } -} - -int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) { - secp256k1_ge Q; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(pubkey != NULL); - memset(pubkey, 0, sizeof(*pubkey)); - ARG_CHECK(input != NULL); - if (!secp256k1_eckey_pubkey_parse(&Q, input, inputlen)) { - return 0; - } - secp256k1_pubkey_save(pubkey, &Q); - secp256k1_ge_clear(&Q); - return 1; -} - -int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey* pubkey, unsigned int flags) { - secp256k1_ge Q; - size_t len; - int ret = 0; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(outputlen != NULL); - ARG_CHECK(*outputlen >= ((flags & SECP256K1_FLAGS_BIT_COMPRESSION) ? 33 : 65)); - len = *outputlen; - *outputlen = 0; - ARG_CHECK(output != NULL); - memset(output, 0, len); - ARG_CHECK(pubkey != NULL); - ARG_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_COMPRESSION); - if (secp256k1_pubkey_load(ctx, &Q, pubkey)) { - ret = secp256k1_eckey_pubkey_serialize(&Q, output, &len, flags & SECP256K1_FLAGS_BIT_COMPRESSION); - if (ret) { - *outputlen = len; - } - } - return ret; -} - -static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig) { - (void)ctx; - if (sizeof(secp256k1_scalar) == 32) { - /* When the secp256k1_scalar type is exactly 32 byte, use its - * representation inside secp256k1_ecdsa_signature, as conversion is very fast. - * Note that secp256k1_ecdsa_signature_save must use the same representation. */ - memcpy(r, &sig->data[0], 32); - memcpy(s, &sig->data[32], 32); - } else { - secp256k1_scalar_set_b32(r, &sig->data[0], NULL); - secp256k1_scalar_set_b32(s, &sig->data[32], NULL); - } -} - -static void secp256k1_ecdsa_signature_save(secp256k1_ecdsa_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s) { - if (sizeof(secp256k1_scalar) == 32) { - memcpy(&sig->data[0], r, 32); - memcpy(&sig->data[32], s, 32); - } else { - secp256k1_scalar_get_b32(&sig->data[0], r); - secp256k1_scalar_get_b32(&sig->data[32], s); - } -} - -int secp256k1_ecdsa_signature_parse_der(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { - secp256k1_scalar r, s; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(sig != NULL); - ARG_CHECK(input != NULL); - - if (secp256k1_ecdsa_sig_parse(&r, &s, input, inputlen)) { - secp256k1_ecdsa_signature_save(sig, &r, &s); - return 1; - } else { - memset(sig, 0, sizeof(*sig)); - return 0; - } -} - -int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input64) { - secp256k1_scalar r, s; - int ret = 1; - int overflow = 0; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(sig != NULL); - ARG_CHECK(input64 != NULL); - - secp256k1_scalar_set_b32(&r, &input64[0], &overflow); - ret &= !overflow; - secp256k1_scalar_set_b32(&s, &input64[32], &overflow); - ret &= !overflow; - if (ret) { - secp256k1_ecdsa_signature_save(sig, &r, &s); - } else { - memset(sig, 0, sizeof(*sig)); - } - return ret; -} - -int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_ecdsa_signature* sig) { - secp256k1_scalar r, s; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(output != NULL); - ARG_CHECK(outputlen != NULL); - ARG_CHECK(sig != NULL); - - secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); - return secp256k1_ecdsa_sig_serialize(output, outputlen, &r, &s); -} - -int secp256k1_ecdsa_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, const secp256k1_ecdsa_signature* sig) { - secp256k1_scalar r, s; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(output64 != NULL); - ARG_CHECK(sig != NULL); - - secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); - secp256k1_scalar_get_b32(&output64[0], &r); - secp256k1_scalar_get_b32(&output64[32], &s); - return 1; -} - -int secp256k1_ecdsa_signature_normalize(const secp256k1_context* ctx, secp256k1_ecdsa_signature *sigout, const secp256k1_ecdsa_signature *sigin) { - secp256k1_scalar r, s; - int ret = 0; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(sigin != NULL); - - secp256k1_ecdsa_signature_load(ctx, &r, &s, sigin); - ret = secp256k1_scalar_is_high(&s); - if (sigout != NULL) { - if (ret) { - secp256k1_scalar_negate(&s, &s); - } - secp256k1_ecdsa_signature_save(sigout, &r, &s); - } - - return ret; -} - -int secp256k1_ecdsa_verify(const secp256k1_context* ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msg32, const secp256k1_pubkey *pubkey) { - secp256k1_ge q; - secp256k1_scalar r, s; - secp256k1_scalar m; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig != NULL); - ARG_CHECK(pubkey != NULL); - - secp256k1_scalar_set_b32(&m, msg32, NULL); - secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); - return (!secp256k1_scalar_is_high(&s) && - secp256k1_pubkey_load(ctx, &q, pubkey) && - secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &r, &s, &q, &m)); -} - -static SECP256K1_INLINE void buffer_append(unsigned char *buf, unsigned int *offset, const void *data, unsigned int len) { - memcpy(buf + *offset, data, len); - *offset += len; -} - -static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { - unsigned char keydata[112]; - unsigned int offset = 0; - secp256k1_rfc6979_hmac_sha256 rng; - unsigned int i; - /* We feed a byte array to the PRNG as input, consisting of: - * - the private key (32 bytes) and message (32 bytes), see RFC 6979 3.2d. - * - optionally 32 extra bytes of data, see RFC 6979 3.6 Additional Data. - * - optionally 16 extra bytes with the algorithm name. - * Because the arguments have distinct fixed lengths it is not possible for - * different argument mixtures to emulate each other and result in the same - * nonces. - */ - buffer_append(keydata, &offset, key32, 32); - buffer_append(keydata, &offset, msg32, 32); - if (data != NULL) { - buffer_append(keydata, &offset, data, 32); - } - if (algo16 != NULL) { - buffer_append(keydata, &offset, algo16, 16); - } - secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, offset); - memset(keydata, 0, sizeof(keydata)); - for (i = 0; i <= counter; i++) { - secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); - } - secp256k1_rfc6979_hmac_sha256_finalize(&rng); - return 1; -} - -const secp256k1_nonce_function secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; -const secp256k1_nonce_function secp256k1_nonce_function_default = nonce_function_rfc6979; - -int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { - secp256k1_scalar r, s; - secp256k1_scalar sec, non, msg; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(signature != NULL); - ARG_CHECK(seckey != NULL); - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; - } - - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - /* Fail if the secret key is invalid. */ - if (!overflow && !secp256k1_scalar_is_zero(&sec)) { - unsigned char nonce32[32]; - unsigned int count = 0; - secp256k1_scalar_set_b32(&msg, msg32, NULL); - while (1) { - ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - if (!overflow && !secp256k1_scalar_is_zero(&non)) { - if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, NULL)) { - break; - } - } - count++; - } - memset(nonce32, 0, 32); - secp256k1_scalar_clear(&msg); - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); - } - if (ret) { - secp256k1_ecdsa_signature_save(signature, &r, &s); - } else { - memset(signature, 0, sizeof(*signature)); - } - return ret; -} - -int secp256k1_ec_seckey_verify(const secp256k1_context* ctx, const unsigned char *seckey) { - secp256k1_scalar sec; - int ret; - int overflow; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(seckey != NULL); - - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - ret = !overflow && !secp256k1_scalar_is_zero(&sec); - secp256k1_scalar_clear(&sec); - return ret; -} - -int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) { - secp256k1_gej pj; - secp256k1_ge p; - secp256k1_scalar sec; - int overflow; - int ret = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(pubkey != NULL); - memset(pubkey, 0, sizeof(*pubkey)); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(seckey != NULL); - - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - ret = (!overflow) & (!secp256k1_scalar_is_zero(&sec)); - if (ret) { - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pj, &sec); - secp256k1_ge_set_gej(&p, &pj); - secp256k1_pubkey_save(pubkey, &p); - } - secp256k1_scalar_clear(&sec); - return ret; -} - -int secp256k1_ec_privkey_negate(const secp256k1_context* ctx, unsigned char *seckey) { - secp256k1_scalar sec; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(seckey != NULL); - - secp256k1_scalar_set_b32(&sec, seckey, NULL); - secp256k1_scalar_negate(&sec, &sec); - secp256k1_scalar_get_b32(seckey, &sec); - - return 1; -} - -int secp256k1_ec_pubkey_negate(const secp256k1_context* ctx, secp256k1_pubkey *pubkey) { - int ret = 0; - secp256k1_ge p; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(pubkey != NULL); - - ret = secp256k1_pubkey_load(ctx, &p, pubkey); - memset(pubkey, 0, sizeof(*pubkey)); - if (ret) { - secp256k1_ge_neg(&p, &p); - secp256k1_pubkey_save(pubkey, &p); - } - return ret; -} - -int secp256k1_ec_privkey_tweak_add(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) { - secp256k1_scalar term; - secp256k1_scalar sec; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(seckey != NULL); - ARG_CHECK(tweak != NULL); - - secp256k1_scalar_set_b32(&term, tweak, &overflow); - secp256k1_scalar_set_b32(&sec, seckey, NULL); - - ret = !overflow && secp256k1_eckey_privkey_tweak_add(&sec, &term); - memset(seckey, 0, 32); - if (ret) { - secp256k1_scalar_get_b32(seckey, &sec); - } - - secp256k1_scalar_clear(&sec); - secp256k1_scalar_clear(&term); - return ret; -} - -int secp256k1_ec_pubkey_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) { - secp256k1_ge p; - secp256k1_scalar term; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(pubkey != NULL); - ARG_CHECK(tweak != NULL); - - secp256k1_scalar_set_b32(&term, tweak, &overflow); - ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); - memset(pubkey, 0, sizeof(*pubkey)); - if (ret) { - if (secp256k1_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &p, &term)) { - secp256k1_pubkey_save(pubkey, &p); - } else { - ret = 0; - } - } - - return ret; -} - -int secp256k1_ec_privkey_tweak_mul(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) { - secp256k1_scalar factor; - secp256k1_scalar sec; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(seckey != NULL); - ARG_CHECK(tweak != NULL); - - secp256k1_scalar_set_b32(&factor, tweak, &overflow); - secp256k1_scalar_set_b32(&sec, seckey, NULL); - ret = !overflow && secp256k1_eckey_privkey_tweak_mul(&sec, &factor); - memset(seckey, 0, 32); - if (ret) { - secp256k1_scalar_get_b32(seckey, &sec); - } - - secp256k1_scalar_clear(&sec); - secp256k1_scalar_clear(&factor); - return ret; -} - -int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) { - secp256k1_ge p; - secp256k1_scalar factor; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(pubkey != NULL); - ARG_CHECK(tweak != NULL); - - secp256k1_scalar_set_b32(&factor, tweak, &overflow); - ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); - memset(pubkey, 0, sizeof(*pubkey)); - if (ret) { - if (secp256k1_eckey_pubkey_tweak_mul(&ctx->ecmult_ctx, &p, &factor)) { - secp256k1_pubkey_save(pubkey, &p); - } else { - ret = 0; - } - } - - return ret; -} - -int secp256k1_context_randomize(secp256k1_context* ctx, const unsigned char *seed32) { - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); - return 1; -} - -int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, const secp256k1_pubkey * const *pubnonces, size_t n) { - size_t i; - secp256k1_gej Qj; - secp256k1_ge Q; - - ARG_CHECK(pubnonce != NULL); - memset(pubnonce, 0, sizeof(*pubnonce)); - ARG_CHECK(n >= 1); - ARG_CHECK(pubnonces != NULL); - - secp256k1_gej_set_infinity(&Qj); - - for (i = 0; i < n; i++) { - secp256k1_pubkey_load(ctx, &Q, pubnonces[i]); - secp256k1_gej_add_ge(&Qj, &Qj, &Q); - } - if (secp256k1_gej_is_infinity(&Qj)) { - return 0; - } - secp256k1_ge_set_gej(&Q, &Qj); - secp256k1_pubkey_save(pubnonce, &Q); - return 1; -} - -#include "modules/ecdh/main_impl.h" -#include "modules/recovery/main_impl.h" diff --git a/Sources/secp256k1/src/util.h b/Sources/secp256k1/src/util.h deleted file mode 100644 index e014750..0000000 --- a/Sources/secp256k1/src/util.h +++ /dev/null @@ -1,121 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_UTIL_H -#define SECP256K1_UTIL_H - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#include -#include -#include - -typedef struct { - void (*fn)(const char *text, void* data); - const void* data; -} secp256k1_callback; - -static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * const cb, const char * const text) { - cb->fn(text, (void*)cb->data); -} - -#ifdef DETERMINISTIC -#define TEST_FAILURE(msg) do { \ - fprintf(stderr, "%s\n", msg); \ - abort(); \ -} while(0); -#else -#define TEST_FAILURE(msg) do { \ - fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \ - abort(); \ -} while(0) -#endif - -#ifdef HAVE_BUILTIN_EXPECT -#define EXPECT(x,c) __builtin_expect((x),(c)) -#else -#define EXPECT(x,c) (x) -#endif - -#ifdef DETERMINISTIC -#define CHECK(cond) do { \ - if (EXPECT(!(cond), 0)) { \ - TEST_FAILURE("test condition failed"); \ - } \ -} while(0) -#else -#define CHECK(cond) do { \ - if (EXPECT(!(cond), 0)) { \ - TEST_FAILURE("test condition failed: " #cond); \ - } \ -} while(0) -#endif - -/* Like assert(), but when VERIFY is defined, and side-effect safe. */ -#if defined(COVERAGE) -#define VERIFY_CHECK(check) -#define VERIFY_SETUP(stmt) -#elif defined(VERIFY) -#define VERIFY_CHECK CHECK -#define VERIFY_SETUP(stmt) do { stmt; } while(0) -#else -#define VERIFY_CHECK(cond) do { (void)(cond); } while(0) -#define VERIFY_SETUP(stmt) -#endif - -static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_t size) { - void *ret = malloc(size); - if (ret == NULL) { - secp256k1_callback_call(cb, "Out of memory"); - } - return ret; -} - -static SECP256K1_INLINE void *checked_realloc(const secp256k1_callback* cb, void *ptr, size_t size) { - void *ret = realloc(ptr, size); - if (ret == NULL) { - secp256k1_callback_call(cb, "Out of memory"); - } - return ret; -} - -/* Macro for restrict, when available and not in a VERIFY build. */ -#if defined(SECP256K1_BUILD) && defined(VERIFY) -# define SECP256K1_RESTRICT -#else -# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) -# if SECP256K1_GNUC_PREREQ(3,0) -# define SECP256K1_RESTRICT __restrict__ -# elif (defined(_MSC_VER) && _MSC_VER >= 1400) -# define SECP256K1_RESTRICT __restrict -# else -# define SECP256K1_RESTRICT -# endif -# else -# define SECP256K1_RESTRICT restrict -# endif -#endif - -#if defined(_WIN32) -# define I64FORMAT "I64d" -# define I64uFORMAT "I64u" -#else -# define I64FORMAT "lld" -# define I64uFORMAT "llu" -#endif - -#if defined(HAVE___INT128) -# if defined(__GNUC__) -# define SECP256K1_GNUC_EXT __extension__ -# else -# define SECP256K1_GNUC_EXT -# endif -SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; -#endif - -#endif /* SECP256K1_UTIL_H */ diff --git a/Tests/UnitTests/Secp256k1.swift b/Tests/UnitTests/Secp256k1.swift index 6b70934..efc5e53 100644 --- a/Tests/UnitTests/Secp256k1.swift +++ b/Tests/UnitTests/Secp256k1.swift @@ -5,20 +5,20 @@ let secretKey = Data(base64Encoded: "LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ class Secp256k1Test: XCTestCase { func testVerifiesSecret() { - XCTAssertTrue(Secp256k1Context.shared.verify(secretKey: secretKey)) + XCTAssertTrue(Secp256k1.shared.verify(secretKey: secretKey)) } func testPublicFromPrivate() { - let publicKey = try? Secp256k1Context.shared.createPublic(fromSecret: secretKey) + let publicKey = try? Secp256k1.shared.createPublic(fromSecret: secretKey) XCTAssertNotNil(publicKey) XCTAssertEqual(publicKey?.base64EncodedString(), "A4fYIELZNEcAjf4q92IGih5T/zlKW/j2igRfpkK5nqXR") } func testSignAndRecover() { let message = Data(base64Encoded: "sEoPAwEAAAAYSg8DAQAAABBLDwMBAAAAaEoPAwEAAAA=")! - let result = try? Secp256k1Context.shared.sign(message: message, secretKey: secretKey) + let result = try? Secp256k1.shared.sign(message: message, secretKey: secretKey) XCTAssertNotNil(result) - let publicKey = try? Secp256k1Context.shared.recover(message: message, signature: result!.0, recoveryId: result!.1) + let publicKey = try? Secp256k1.shared.recover(message: message, signature: result!.0, recoveryId: result!.1) XCTAssertEqual(publicKey?.base64EncodedString(), "A4fYIELZNEcAjf4q92IGih5T/zlKW/j2igRfpkK5nqXR") } } From ae4700f64b031b3342b2d3585e4b750c63553563 Mon Sep 17 00:00:00 2001 From: Vladimir Babin Date: Fri, 9 Feb 2024 11:31:46 +0300 Subject: [PATCH 2/2] Update Crypto --- Sources/Crypto/base58.c | 401 +++++++----------- Sources/Crypto/hasher.c | 96 ----- Sources/Crypto/hasher.h | 62 --- Sources/Crypto/{ => include}/base58.h | 21 +- Sources/Crypto/include/crypto.h | 10 +- Sources/Crypto/include/ripemd160.h | 22 + Sources/Crypto/{ => include}/sha2.h | 2 +- Sources/Crypto/memzero.c | 66 ++- Sources/Crypto/memzero.h | 2 +- Sources/Crypto/options.h | 94 ---- Sources/Crypto/ripemd160.c | 19 +- Sources/Crypto/ripemd160.h | 20 - Sources/Crypto/sha2.c | 86 ++-- Sources/VIZ/Base58.swift | 59 --- .../VIZ/Extensions/Data+Base58Encoding.swift | 87 ++++ Sources/VIZ/Extensions/Data+RIPEMD160.swift | 20 + Sources/VIZ/Extensions/Data+SHA2.swift | 35 ++ Sources/VIZ/PrivateKey.swift | 4 +- Sources/VIZ/PublicKey.swift | 4 +- Sources/VIZ/Random.swift | 39 -- Sources/VIZ/Sha2.swift | 18 - Sources/VIZ/Transaction.swift | 3 +- Tests/UnitTests/Base58.swift | 8 +- Tests/UnitTests/Sha2.swift | 2 +- 24 files changed, 458 insertions(+), 722 deletions(-) mode change 100755 => 100644 Sources/Crypto/base58.c delete mode 100755 Sources/Crypto/hasher.c delete mode 100755 Sources/Crypto/hasher.h rename Sources/Crypto/{ => include}/base58.h (62%) mode change 100755 => 100644 create mode 100644 Sources/Crypto/include/ripemd160.h rename Sources/Crypto/{ => include}/sha2.h (98%) mode change 100755 => 100644 mode change 100755 => 100644 Sources/Crypto/memzero.c mode change 100755 => 100644 Sources/Crypto/memzero.h delete mode 100755 Sources/Crypto/options.h mode change 100755 => 100644 Sources/Crypto/ripemd160.c delete mode 100755 Sources/Crypto/ripemd160.h mode change 100755 => 100644 Sources/Crypto/sha2.c delete mode 100644 Sources/VIZ/Base58.swift create mode 100644 Sources/VIZ/Extensions/Data+Base58Encoding.swift create mode 100644 Sources/VIZ/Extensions/Data+RIPEMD160.swift create mode 100644 Sources/VIZ/Extensions/Data+SHA2.swift delete mode 100644 Sources/VIZ/Random.swift delete mode 100644 Sources/VIZ/Sha2.swift diff --git a/Sources/Crypto/base58.c b/Sources/Crypto/base58.c old mode 100755 new mode 100644 index 5afbbd0..2799977 --- a/Sources/Crypto/base58.c +++ b/Sources/Crypto/base58.c @@ -1,6 +1,7 @@ /** * Copyright (c) 2012-2014 Luke Dashjr * Copyright (c) 2013-2014 Pavol Rusnak + * Copyright (c) 2019 Johan Nordberg * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), @@ -21,261 +22,169 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include +#include "include/base58.h" + #include -#include -#include "base58.h" -#include "sha2.h" -#include "ripemd160.h" +#include + #include "memzero.h" -static const int8_t b58digits_map[] = { - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1, - -1, 9,10,11,12,13,14,15,16,-1,17,18,19,20,21,-1, - 22,23,24,25,26,27,28,29,30,31,32,-1,-1,-1,-1,-1, - -1,33,34,35,36,37,38,39,40,41,42,43,-1,44,45,46, - 47,48,49,50,51,52,53,54,55,56,57,-1,-1,-1,-1,-1, +const char b58digits_ordered[] = + "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + +const int8_t b58digits_map[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, + 8, -1, -1, -1, -1, -1, -1, -1, 9, 10, 11, 12, 13, 14, 15, 16, -1, 17, 18, + 19, 20, 21, -1, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, + -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, -1, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, }; -bool b58tobin(void *bin, size_t *binszp, const char *b58) -{ - size_t binsz = *binszp; - const unsigned char *b58u = (const unsigned char*)b58; - unsigned char *binu = bin; - size_t outisz = (binsz + 3) / 4; - uint32_t outi[outisz]; - uint64_t t; - uint32_t c; - size_t i, j; - uint8_t bytesleft = binsz % 4; - uint32_t zeromask = bytesleft ? (0xffffffff << (bytesleft * 8)) : 0; - unsigned zerocount = 0; - size_t b58sz; - - b58sz = strlen(b58); - - memset(outi, 0, outisz * sizeof(*outi)); - - // Leading zeros, just count - for (i = 0; i < b58sz && b58u[i] == '1'; ++i) - ++zerocount; - - for ( ; i < b58sz; ++i) - { - if (b58u[i] & 0x80) - // High-bit set on invalid digit - return false; - if (b58digits_map[b58u[i]] == -1) - // Invalid base58 digit - return false; - c = (unsigned)b58digits_map[b58u[i]]; - for (j = outisz; j--; ) - { - t = ((uint64_t)outi[j]) * 58 + c; - c = (t & 0x3f00000000) >> 32; - outi[j] = t & 0xffffffff; - } - if (c) - // Output number too big (carry to the next int32) - return false; - if (outi[0] & zeromask) - // Output number too big (last int32 filled too far) - return false; - } - - j = 0; - switch (bytesleft) { - case 3: - *(binu++) = (outi[0] & 0xff0000) >> 16; - //-fallthrough - case 2: - *(binu++) = (outi[0] & 0xff00) >> 8; - //-fallthrough - case 1: - *(binu++) = (outi[0] & 0xff); - ++j; - //-fallthrough - default: - break; - } - - for (; j < outisz; ++j) - { - *(binu++) = (outi[j] >> 0x18) & 0xff; - *(binu++) = (outi[j] >> 0x10) & 0xff; - *(binu++) = (outi[j] >> 8) & 0xff; - *(binu++) = (outi[j] >> 0) & 0xff; - } - - // Count canonical base58 byte count - binu = bin; - for (i = 0; i < binsz; ++i) - { - if (binu[i]) { - if (zerocount > i) { - /* result too large */ - return false; - } - break; - } - --*binszp; - } - *binszp += zerocount; - - return true; -} - -int b58check(const void *bin, size_t binsz, HasherType hasher_type, const char *base58str) -{ - unsigned char buf[32]; - const uint8_t *binc = bin; - unsigned i; - if (binsz < 4) - return -4; - hasher_Raw(hasher_type, bin, binsz - 4, buf); - if (memcmp(&binc[binsz - 4], buf, 4)) - return -1; - - // Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end) - for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i) - {} // Just finding the end of zeros, nothing to do in loop - if (binc[i] == '\0' || base58str[i] == '1') - return -3; - - return binc[0]; +typedef uint64_t b58_maxint_t; +typedef uint32_t b58_almostmaxint_t; +#define b58_almostmaxint_bits (sizeof(b58_almostmaxint_t) * 8) +static const b58_almostmaxint_t b58_almostmaxint_mask = + ((((b58_maxint_t)1) << b58_almostmaxint_bits) - 1); + +bool b58tobin(void *bin, size_t *binszp, const char *b58) { + size_t binsz = *binszp; + + if (binsz == 0) { + return false; + } + + const unsigned char *b58u = (const unsigned char *)b58; + unsigned char *binu = bin; + size_t outisz = + (binsz + sizeof(b58_almostmaxint_t) - 1) / sizeof(b58_almostmaxint_t); + b58_almostmaxint_t outi[outisz]; + b58_maxint_t t = 0; + b58_almostmaxint_t c = 0; + size_t i = 0, j = 0; + uint8_t bytesleft = binsz % sizeof(b58_almostmaxint_t); + b58_almostmaxint_t zeromask = + bytesleft ? (b58_almostmaxint_mask << (bytesleft * 8)) : 0; + unsigned zerocount = 0; + + size_t b58sz = strlen(b58); + + memzero(outi, sizeof(outi)); + + // Leading zeros, just count + for (i = 0; i < b58sz && b58u[i] == '1'; ++i) ++zerocount; + + for (; i < b58sz; ++i) { + if (b58u[i] & 0x80) + // High-bit set on invalid digit + return false; + if (b58digits_map[b58u[i]] == -1) + // Invalid base58 digit + return false; + c = (unsigned)b58digits_map[b58u[i]]; + for (j = outisz; j--;) { + t = ((b58_maxint_t)outi[j]) * 58 + c; + c = t >> b58_almostmaxint_bits; + outi[j] = t & b58_almostmaxint_mask; + } + if (c) + // Output number too big (carry to the next int32) + return false; + if (outi[0] & zeromask) + // Output number too big (last int32 filled too far) + return false; + } + + j = 0; + if (bytesleft) { + for (i = bytesleft; i > 0; --i) { + *(binu++) = (outi[0] >> (8 * (i - 1))) & 0xff; + } + ++j; + } + + for (; j < outisz; ++j) { + for (i = sizeof(*outi); i > 0; --i) { + *(binu++) = (outi[j] >> (8 * (i - 1))) & 0xff; + } + } + + // Count canonical base58 byte count + binu = bin; + for (i = 0; i < binsz; ++i) { + if (binu[i]) { + if (zerocount > i) { + /* result too large */ + return false; + } + + break; + } + --*binszp; + } + *binszp += zerocount; + + return true; } -static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; - -bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) -{ - const uint8_t *bin = data; - int carry; - ssize_t i, j, high, zcount = 0; - size_t size; - - while (zcount < (ssize_t)binsz && !bin[zcount]) - ++zcount; - - size = (binsz - zcount) * 138 / 100 + 1; - uint8_t buf[size]; - memset(buf, 0, size); - - for (i = zcount, high = size - 1; i < (ssize_t)binsz; ++i, high = j) - { - for (carry = bin[i], j = size - 1; (j > high) || carry; --j) - { - carry += 256 * buf[j]; - buf[j] = carry % 58; - carry /= 58; - } - } - - for (j = 0; j < (ssize_t)size && !buf[j]; ++j); - - if (*b58sz <= zcount + size - j) - { - *b58sz = zcount + size - j + 1; - return false; - } - - if (zcount) - memset(b58, '1', zcount); - for (i = zcount; j < (ssize_t)size; ++i, ++j) - b58[i] = b58digits_ordered[buf[j]]; - b58[i] = '\0'; - *b58sz = i + 1; - - return true; -} - -int base58_encode_check(const uint8_t *data, int datalen, HasherType hasher_type, char *str, int strsize) -{ - if (datalen > 128) { - return 0; - } - uint8_t buf[datalen + 32]; - uint8_t *hash = buf + datalen; - memcpy(buf, data, datalen); - hasher_Raw(hasher_type, data, datalen, hash); - size_t res = strsize; - bool success = b58enc(str, &res, buf, datalen + 4); - memzero(buf, sizeof(buf)); - return success ? res : 0; -} - -int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, int datalen) -{ - if (datalen > 128) { - return 0; - } - uint8_t d[datalen + 4]; - size_t res = datalen + 4; - if (b58tobin(d, &res, str) != true) { - return 0; - } - uint8_t *nd = d + datalen + 4 - res; - if (b58check(nd, res, hasher_type, str) < 0) { - return 0; - } - memcpy(data, nd, res - 4); - return res - 4; -} - -#if USE_GRAPHENE -int b58gphcheck(const void *bin, size_t binsz, const char *base58str) -{ - unsigned char buf[32]; - const uint8_t *binc = bin; - unsigned i; - if (binsz < 4) - return -4; - ripemd160(bin, binsz - 4, buf); // No double SHA256, but a single RIPEMD160 - if (memcmp(&binc[binsz - 4], buf, 4)) - return -1; - - // Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end) - for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i) - {} // Just finding the end of zeros, nothing to do in loop - if (binc[i] == '\0' || base58str[i] == '1') - return -3; - - return binc[0]; +bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) { + const uint8_t *bin = data; + int carry = 0; + size_t i = 0, j = 0, high = 0, zcount = 0; + size_t size = 0; + + while (zcount < binsz && !bin[zcount]) ++zcount; + + size = (binsz - zcount) * 138 / 100 + 1; + uint8_t buf[size]; + memzero(buf, size); + + for (i = zcount, high = size - 1; i < binsz; ++i, high = j) { + for (carry = bin[i], j = size - 1; (j > high) || carry; --j) { + carry += 256 * buf[j]; + buf[j] = carry % 58; + carry /= 58; + if (!j) { + // Otherwise j wraps to maxint which is > high + break; + } + } + } + + for (j = 0; j < size && !buf[j]; ++j) + ; + + if (*b58sz <= zcount + size - j) { + *b58sz = zcount + size - j + 1; + return false; + } + + if (zcount) memset(b58, '1', zcount); + for (i = zcount; j < size; ++i, ++j) b58[i] = b58digits_ordered[buf[j]]; + b58[i] = '\0'; + *b58sz = i + 1; + + return true; } -int base58gph_encode_check(const uint8_t *data, int datalen, char *str, int strsize) -{ - if (datalen > 128) { - return 0; - } - uint8_t buf[datalen + 32]; - uint8_t *hash = buf + datalen; - memcpy(buf, data, datalen); - ripemd160(data, datalen, hash); // No double SHA256, but a single RIPEMD160 - size_t res = strsize; - bool success = b58enc(str, &res, buf, datalen + 4); - memzero(buf, sizeof(buf)); - return success ? res : 0; +size_t base58_encode(const uint8_t *data, size_t datalen, char *str, + size_t strsize) { + size_t res = strsize; + if (!b58enc(str, &res, data, datalen)) { + return 0; + } + return res; } -int base58gph_decode_check(const char *str, uint8_t *data, int datalen) -{ - if (datalen > 128) { - return 0; - } - uint8_t d[datalen + 4]; - size_t res = datalen + 4; - if (b58tobin(d, &res, str) != true) { - return 0; - } - uint8_t *nd = d + datalen + 4 - res; - if (b58gphcheck(nd, res, str) < 0) { - return 0; - } - memcpy(data, nd, res - 4); - return res - 4; +size_t base58_decode(const char *str, uint8_t *data, size_t datalen) { + uint8_t d[datalen]; + memset(d, 0, sizeof(d)); + size_t res = datalen; + if (b58tobin(d, &res, str) != true) { + return 0; + } + uint8_t *nd = d + datalen - res; + memcpy(data, nd, res); + return res; } -#endif diff --git a/Sources/Crypto/hasher.c b/Sources/Crypto/hasher.c deleted file mode 100755 index c9af3cf..0000000 --- a/Sources/Crypto/hasher.c +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright (c) 2017 Saleem Rashid - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES - * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "hasher.h" - -void hasher_Init(Hasher *hasher, HasherType type) { - hasher->type = type; - - switch (hasher->type) { - case HASHER_SHA2: - case HASHER_SHA2D: - sha256_Init(&hasher->ctx.sha2); - break; - // case HASHER_BLAKE: - // case HASHER_BLAKED: - // blake256_Init(&hasher->ctx.blake); - // break; - // case HASHER_GROESTLD_TRUNC: - // groestl512_Init(&hasher->ctx.groestl); - // break; - } -} - -void hasher_Reset(Hasher *hasher) { - hasher_Init(hasher, hasher->type); -} - -void hasher_Update(Hasher *hasher, const uint8_t *data, size_t length) { - switch (hasher->type) { - case HASHER_SHA2: - case HASHER_SHA2D: - sha256_Update(&hasher->ctx.sha2, data, length); - break; - // case HASHER_BLAKE: - // case HASHER_BLAKED: - // blake256_Update(&hasher->ctx.blake, data, length); - // break; - // case HASHER_GROESTLD_TRUNC: - // groestl512_Update(&hasher->ctx.groestl, data, length); - // break; - } -} - -void hasher_Final(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]) { - switch (hasher->type) { - case HASHER_SHA2: - case HASHER_SHA2D: - sha256_Final(&hasher->ctx.sha2, hash); - break; - // case HASHER_BLAKE: - // case HASHER_BLAKED: - // blake256_Final(&hasher->ctx.blake, hash); - // break; - // case HASHER_GROESTLD_TRUNC: - // groestl512_DoubleTrunc(&hasher->ctx.groestl, hash); - // return; - } - - switch (hasher->type) { - case HASHER_SHA2D: - hasher_Raw(HASHER_SHA2, hash, HASHER_DIGEST_LENGTH, hash); - break; - // case HASHER_BLAKED: - // hasher_Raw(HASHER_BLAKE, hash, HASHER_DIGEST_LENGTH, hash); - // break; - default: - break; - } -} - -void hasher_Raw(HasherType type, const uint8_t *data, size_t length, uint8_t hash[HASHER_DIGEST_LENGTH]) { - Hasher hasher; - - hasher_Init(&hasher, type); - hasher_Update(&hasher, data, length); - hasher_Final(&hasher, hash); -} diff --git a/Sources/Crypto/hasher.h b/Sources/Crypto/hasher.h deleted file mode 100755 index ca31fc8..0000000 --- a/Sources/Crypto/hasher.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (c) 2017 Saleem Rashid - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES - * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef __HASHER_H__ -#define __HASHER_H__ - -#include -#include - -#include "sha2.h" -// #include "blake256.h" -// #include "groestl.h" - -#define HASHER_DIGEST_LENGTH 32 - -typedef enum { - HASHER_SHA2, - // HASHER_BLAKE, - - HASHER_SHA2D, - // HASHER_BLAKED, - - // HASHER_GROESTLD_TRUNC, /* Double Groestl512 hasher truncated to 256 bits */ -} HasherType; - -typedef struct { - HasherType type; - - union { - SHA256_CTX sha2; -// BLAKE256_CTX blake; -// GROESTL512_CTX groestl; - } ctx; -} Hasher; - -void hasher_Init(Hasher *hasher, HasherType type); -void hasher_Reset(Hasher *hasher); -void hasher_Update(Hasher *hasher, const uint8_t *data, size_t length); -void hasher_Final(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]); - -void hasher_Raw(HasherType type, const uint8_t *data, size_t length, uint8_t hash[HASHER_DIGEST_LENGTH]); - -#endif diff --git a/Sources/Crypto/base58.h b/Sources/Crypto/include/base58.h old mode 100755 new mode 100644 similarity index 62% rename from Sources/Crypto/base58.h rename to Sources/Crypto/include/base58.h index 41b0b7d..f3d29a7 --- a/Sources/Crypto/base58.h +++ b/Sources/Crypto/include/base58.h @@ -1,6 +1,7 @@ /** * Copyright (c) 2013-2014 Tomas Dzetkulic * Copyright (c) 2013-2014 Pavol Rusnak + * Copyright (c) 2019 Johan Nordberg * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), @@ -24,23 +25,11 @@ #ifndef __BASE58_H__ #define __BASE58_H__ +#include #include -#include -#include "hasher.h" -#include "options.h" -int base58_encode_check(const uint8_t *data, int len, HasherType hasher_type, char *str, int strsize); -int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, int datalen); - -// Private -bool b58tobin(void *bin, size_t *binszp, const char *b58); -int b58check(const void *bin, size_t binsz, HasherType hasher_type, const char *base58str); -bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz); - -#if USE_GRAPHENE -int base58gph_encode_check(const uint8_t *data, int datalen, char *str, int strsize); -int base58gph_decode_check(const char *str, uint8_t *data, int datalen); -int b58gphcheck(const void *bin, size_t binsz, const char *base58str); -#endif +size_t base58_encode(const uint8_t *data, size_t datalen, char *str, + size_t strsize); +size_t base58_decode(const char *str, uint8_t *data, size_t datalen); #endif diff --git a/Sources/Crypto/include/crypto.h b/Sources/Crypto/include/crypto.h index 2165d74..5874bf8 100644 --- a/Sources/Crypto/include/crypto.h +++ b/Sources/Crypto/include/crypto.h @@ -1,6 +1,8 @@ -#ifndef CRYPTO_H__ -#define CRYPTO_H__ +#ifndef __CRYPTO_H__ +#define __CRYPTO_H__ -#include "../base58.h" +#include "base58.h" +#include "ripemd160.h" +#include "sha2.h" -#endif \ No newline at end of file +#endif diff --git a/Sources/Crypto/include/ripemd160.h b/Sources/Crypto/include/ripemd160.h new file mode 100644 index 0000000..8256b08 --- /dev/null +++ b/Sources/Crypto/include/ripemd160.h @@ -0,0 +1,22 @@ +#ifndef __RIPEMD160_H__ +#define __RIPEMD160_H__ + +#include + +#define RIPEMD160_BLOCK_LENGTH 64 +#define RIPEMD160_DIGEST_LENGTH 20 + +typedef struct _RIPEMD160_CTX { + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[5]; /*!< intermediate digest state */ + uint8_t buffer[RIPEMD160_BLOCK_LENGTH]; /*!< data block being processed */ +} RIPEMD160_CTX; + +void ripemd160_Init(RIPEMD160_CTX *ctx); +void ripemd160_Update(RIPEMD160_CTX *ctx, const uint8_t *input, uint32_t ilen); +void ripemd160_Final(RIPEMD160_CTX *ctx, + uint8_t output[RIPEMD160_DIGEST_LENGTH]); +void ripemd160(const uint8_t *msg, uint32_t msg_len, + uint8_t hash[RIPEMD160_DIGEST_LENGTH]); + +#endif diff --git a/Sources/Crypto/sha2.h b/Sources/Crypto/include/sha2.h old mode 100755 new mode 100644 similarity index 98% rename from Sources/Crypto/sha2.h rename to Sources/Crypto/include/sha2.h index 7f519c5..7c468c4 --- a/Sources/Crypto/sha2.h +++ b/Sources/Crypto/include/sha2.h @@ -74,7 +74,7 @@ typedef struct _SHA512_CTX { #define REVERSE32(w,x) { \ uint32_t tmp = (w); \ tmp = (tmp >> 16) | (tmp << 16); \ - (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ + (x) = ((tmp & (uint32_t)0xff00ff00UL) >> 8) | ((tmp & (uint32_t)0x00ff00ffUL) << 8); \ } #define REVERSE64(w,x) { \ uint64_t tmp = (w); \ diff --git a/Sources/Crypto/memzero.c b/Sources/Crypto/memzero.c old mode 100755 new mode 100644 index 68fad58..6a517ff --- a/Sources/Crypto/memzero.c +++ b/Sources/Crypto/memzero.c @@ -1,6 +1,66 @@ +#ifndef __STDC_WANT_LIB_EXT1__ +#define __STDC_WANT_LIB_EXT1__ 1 // C11's bounds-checking interface. +#endif #include -void memzero(void *s, size_t n) -{ - memset(s, 0, n); +#ifdef _WIN32 +#include +#endif + +#ifdef __unix__ +#include +#include +#endif + +// C11's bounds-checking interface. +#if defined(__STDC_LIB_EXT1__) +#define HAVE_MEMSET_S 1 +#endif + +// GNU C Library version 2.25 or later. +#if defined(__GLIBC__) && \ + (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)) +#define HAVE_EXPLICIT_BZERO 1 +#endif + +// Newlib +#if defined(__NEWLIB__) +#define HAVE_EXPLICIT_BZERO 1 +#endif + +// FreeBSD version 11.0 or later. +#if defined(__FreeBSD__) && __FreeBSD_version >= 1100037 +#define HAVE_EXPLICIT_BZERO 1 +#endif + +// OpenBSD version 5.5 or later. +#if defined(__OpenBSD__) && OpenBSD >= 201405 +#define HAVE_EXPLICIT_BZERO 1 +#endif + +// NetBSD version 7.2 or later. +#if defined(__NetBSD__) && __NetBSD_Version__ >= 702000000 +#define HAVE_EXPLICIT_MEMSET 1 +#endif + +// Adapted from +// https://github.com/jedisct1/libsodium/blob/1647f0d53ae0e370378a9195477e3df0a792408f/src/libsodium/sodium/utils.c#L102-L130 + +void memzero(void *const pnt, const size_t len) { +#ifdef _WIN32 + SecureZeroMemory(pnt, len); +#elif defined(HAVE_MEMSET_S) + memset_s(pnt, (rsize_t)len, 0, (rsize_t)len); +#elif defined(HAVE_EXPLICIT_BZERO) + explicit_bzero(pnt, len); +#elif defined(HAVE_EXPLICIT_MEMSET) + explicit_memset(pnt, 0, len); +#else + volatile unsigned char *volatile pnt_ = (volatile unsigned char *volatile)pnt; + size_t i = (size_t)0U; + + while (i < len) { + pnt_[i++] = 0U; + } +#endif } diff --git a/Sources/Crypto/memzero.h b/Sources/Crypto/memzero.h old mode 100755 new mode 100644 index ce51aca..0a959fb --- a/Sources/Crypto/memzero.h +++ b/Sources/Crypto/memzero.h @@ -3,6 +3,6 @@ #include -void memzero(void *s, size_t n); +void memzero(void* const pnt, const size_t len); #endif diff --git a/Sources/Crypto/options.h b/Sources/Crypto/options.h deleted file mode 100755 index e74d004..0000000 --- a/Sources/Crypto/options.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright (c) 2013-2014 Pavol Rusnak - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES - * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef __OPTIONS_H__ -#define __OPTIONS_H__ - -// use precomputed Curve Points (some scalar multiples of curve base point G) -#ifndef USE_PRECOMPUTED_CP -#define USE_PRECOMPUTED_CP 1 -#endif - -// use fast inverse method -#ifndef USE_INVERSE_FAST -#define USE_INVERSE_FAST 1 -#endif - -// support for printing bignum256 structures via printf -#ifndef USE_BN_PRINT -#define USE_BN_PRINT 0 -#endif - -// use deterministic signatures -#ifndef USE_RFC6979 -#define USE_RFC6979 1 -#endif - -// implement BIP32 caching -#ifndef USE_BIP32_CACHE -#define USE_BIP32_CACHE 1 -#define BIP32_CACHE_SIZE 10 -#define BIP32_CACHE_MAXDEPTH 8 -#endif - -// support constructing BIP32 nodes from ed25519 and curve25519 curves. -#ifndef USE_BIP32_25519_CURVES -#define USE_BIP32_25519_CURVES 1 -#endif - -// implement BIP39 caching -#ifndef USE_BIP39_CACHE -#define USE_BIP39_CACHE 1 -#define BIP39_CACHE_SIZE 4 -#endif - -// support Ethereum operations -#ifndef USE_ETHEREUM -#define USE_ETHEREUM 0 -#endif - -// support Graphene operations (VIZ, BitShares) -#ifndef USE_GRAPHENE -#define USE_GRAPHENE 1 -#endif - -// support NEM operations -#ifndef USE_NEM -#define USE_NEM 0 -#endif - -// support MONERO operations -#ifndef USE_MONERO -#define USE_MONERO 0 -#endif - -// support Keccak hashing -#ifndef USE_KECCAK -#define USE_KECCAK 1 -#endif - -// add way how to mark confidential data -#ifndef CONFIDENTIAL -#define CONFIDENTIAL -#endif - -#endif diff --git a/Sources/Crypto/ripemd160.c b/Sources/Crypto/ripemd160.c old mode 100755 new mode 100644 index 66b13ca..352c4e9 --- a/Sources/Crypto/ripemd160.c +++ b/Sources/Crypto/ripemd160.c @@ -25,9 +25,10 @@ * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 */ +#include "include/ripemd160.h" + #include -#include "ripemd160.h" #include "memzero.h" /* @@ -58,7 +59,7 @@ */ void ripemd160_Init(RIPEMD160_CTX *ctx) { - memset(ctx, 0, sizeof(RIPEMD160_CTX)); + memzero(ctx, sizeof(RIPEMD160_CTX)); ctx->total[0] = 0; ctx->total[1] = 0; ctx->state[0] = 0x67452301; @@ -74,7 +75,7 @@ void ripemd160_Init(RIPEMD160_CTX *ctx) */ void ripemd160_process( RIPEMD160_CTX *ctx, const uint8_t data[RIPEMD160_BLOCK_LENGTH] ) { - uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; + uint32_t A = 0, B = 0, C = 0, D = 0, E = 0, Ap = 0, Bp = 0, Cp = 0, Dp = 0, Ep = 0, X[16] = {0}; GET_UINT32_LE( X[ 0], data, 0 ); GET_UINT32_LE( X[ 1], data, 4 ); @@ -255,8 +256,8 @@ void ripemd160_process( RIPEMD160_CTX *ctx, const uint8_t data[RIPEMD160_BLOCK_L */ void ripemd160_Update( RIPEMD160_CTX *ctx, const uint8_t *input, uint32_t ilen ) { - uint32_t fill; - uint32_t left; + uint32_t fill = 0; + uint32_t left = 0; if( ilen == 0 ) return; @@ -305,9 +306,9 @@ static const uint8_t ripemd160_padding[RIPEMD160_BLOCK_LENGTH] = */ void ripemd160_Final( RIPEMD160_CTX *ctx, uint8_t output[RIPEMD160_DIGEST_LENGTH] ) { - uint32_t last, padn; - uint32_t high, low; - uint8_t msglen[8]; + uint32_t last = 0; uint32_t padn = 0; + uint32_t high = 0; uint32_t low = 0; + uint8_t msglen[8] = {0}; high = ( ctx->total[0] >> 29 ) | ( ctx->total[1] << 3 ); @@ -336,7 +337,7 @@ void ripemd160_Final( RIPEMD160_CTX *ctx, uint8_t output[RIPEMD160_DIGEST_LENGTH */ void ripemd160(const uint8_t *msg, uint32_t msg_len, uint8_t hash[RIPEMD160_DIGEST_LENGTH]) { - RIPEMD160_CTX ctx; + RIPEMD160_CTX ctx = {0}; ripemd160_Init( &ctx ); ripemd160_Update( &ctx, msg, msg_len ); ripemd160_Final( &ctx, hash ); diff --git a/Sources/Crypto/ripemd160.h b/Sources/Crypto/ripemd160.h deleted file mode 100755 index a62de5c..0000000 --- a/Sources/Crypto/ripemd160.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __RIPEMD160_H__ -#define __RIPEMD160_H__ - -#include - -#define RIPEMD160_BLOCK_LENGTH 64 -#define RIPEMD160_DIGEST_LENGTH 20 - -typedef struct _RIPEMD160_CTX { - uint32_t total[2]; /*!< number of bytes processed */ - uint32_t state[5]; /*!< intermediate digest state */ - uint8_t buffer[RIPEMD160_BLOCK_LENGTH]; /*!< data block being processed */ -} RIPEMD160_CTX; - -void ripemd160_Init(RIPEMD160_CTX *ctx); -void ripemd160_Update(RIPEMD160_CTX *ctx, const uint8_t *input, uint32_t ilen); -void ripemd160_Final(RIPEMD160_CTX *ctx, uint8_t output[RIPEMD160_DIGEST_LENGTH]); -void ripemd160(const uint8_t *msg, uint32_t msg_len, uint8_t hash[RIPEMD160_DIGEST_LENGTH]); - -#endif diff --git a/Sources/Crypto/sha2.c b/Sources/Crypto/sha2.c old mode 100755 new mode 100644 index 39c1aac..b37e5cb --- a/Sources/Crypto/sha2.c +++ b/Sources/Crypto/sha2.c @@ -321,10 +321,10 @@ void sha1_Init(SHA1_CTX* context) { j++; void sha1_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { - sha2_word32 a, b, c, d, e; - sha2_word32 T1; - sha2_word32 W1[16]; - int j; + sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0; + sha2_word32 T1 = 0; + sha2_word32 W1[16] = {0}; + int j = 0; /* Initialize registers with the prev. intermediate value */ a = state_in[0]; @@ -439,10 +439,10 @@ void sha1_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_w #else /* SHA2_UNROLL_TRANSFORM */ void sha1_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { - sha2_word32 a, b, c, d, e; - sha2_word32 T1; - sha2_word32 W1[16]; - int j; + sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0; + sha2_word32 T1 = 0; + sha2_word32 W1[16] = {0}; + int j = 0; /* Initialize registers with the prev. intermediate value */ a = state_in[0]; @@ -520,7 +520,7 @@ void sha1_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_w #endif /* SHA2_UNROLL_TRANSFORM */ void sha1_Update(SHA1_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace, usedspace; + unsigned int freespace = 0, usedspace = 0; if (len == 0) { /* Calling with no data is valid - we do nothing */ @@ -578,7 +578,7 @@ void sha1_Update(SHA1_CTX* context, const sha2_byte *data, size_t len) { } void sha1_Final(SHA1_CTX* context, sha2_byte digest[]) { - unsigned int usedspace; + unsigned int usedspace = 0; /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { @@ -632,8 +632,8 @@ void sha1_Final(SHA1_CTX* context, sha2_byte digest[]) { } char *sha1_End(SHA1_CTX* context, char buffer[]) { - sha2_byte digest[SHA1_DIGEST_LENGTH], *d = digest; - int i; + sha2_byte digest[SHA1_DIGEST_LENGTH] = {0}, *d = digest; + int i = 0; if (buffer != (char*)0) { sha1_Final(context, digest); @@ -652,14 +652,14 @@ char *sha1_End(SHA1_CTX* context, char buffer[]) { } void sha1_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA1_DIGEST_LENGTH]) { - SHA1_CTX context; + SHA1_CTX context = {0}; sha1_Init(&context); sha1_Update(&context, data, len); sha1_Final(&context, digest); } char* sha1_Data(const sha2_byte* data, size_t len, char digest[SHA1_DIGEST_STRING_LENGTH]) { - SHA1_CTX context; + SHA1_CTX context = {0}; sha1_Init(&context); sha1_Update(&context, data, len); @@ -699,10 +699,10 @@ void sha256_Init(SHA256_CTX* context) { j++ void sha256_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1; - sha2_word32 W256[16]; - int j; + sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; + sha2_word32 T1 = 0; + sha2_word32 W256[16] = {0}; + int j = 0; /* Initialize registers with the prev. intermediate value */ a = state_in[0]; @@ -756,9 +756,9 @@ void sha256_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2 #else /* SHA2_UNROLL_TRANSFORM */ void sha256_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1, T2, W256[16]; - int j; + sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; + sha2_word32 T1 = 0, T2 = 0 , W256[16] = {0}; + int j = 0; /* Initialize registers with the prev. intermediate value */ a = state_in[0]; @@ -791,7 +791,7 @@ void sha256_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2 /* Part of the message block expansion: */ s0 = W256[(j+1)&0x0f]; s0 = sigma0_256(s0); - s1 = W256[(j+14)&0x0f]; + s1 = W256[(j+14)&0x0f]; s1 = sigma1_256(s1); /* Apply the SHA-256 compression function to update a..h */ @@ -827,7 +827,7 @@ void sha256_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2 #endif /* SHA2_UNROLL_TRANSFORM */ void sha256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace, usedspace; + unsigned int freespace = 0, usedspace = 0; if (len == 0) { /* Calling with no data is valid - we do nothing */ @@ -885,14 +885,14 @@ void sha256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { } void sha256_Final(SHA256_CTX* context, sha2_byte digest[]) { - unsigned int usedspace; + unsigned int usedspace = 0; /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; /* Begin padding with a 1 bit: */ ((uint8_t*)context->buffer)[usedspace++] = 0x80; - + if (usedspace > SHA256_SHORT_BLOCK_LENGTH) { memzero(((uint8_t*)context->buffer) + usedspace, SHA256_BLOCK_LENGTH - usedspace); @@ -904,7 +904,7 @@ void sha256_Final(SHA256_CTX* context, sha2_byte digest[]) { #endif /* Do second-to-last transform: */ sha256_Transform(context->state, context->buffer, context->state); - + /* And prepare the last transform: */ usedspace = 0; } @@ -939,8 +939,8 @@ void sha256_Final(SHA256_CTX* context, sha2_byte digest[]) { } char *sha256_End(SHA256_CTX* context, char buffer[]) { - sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; - int i; + sha2_byte digest[SHA256_DIGEST_LENGTH] = {0}, *d = digest; + int i = 0; if (buffer != (char*)0) { sha256_Final(context, digest); @@ -959,14 +959,14 @@ char *sha256_End(SHA256_CTX* context, char buffer[]) { } void sha256_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA256_DIGEST_LENGTH]) { - SHA256_CTX context; + SHA256_CTX context = {0}; sha256_Init(&context); sha256_Update(&context, data, len); sha256_Final(&context, digest); } char* sha256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { - SHA256_CTX context; + SHA256_CTX context = {0}; sha256_Init(&context); sha256_Update(&context, data, len); @@ -1006,9 +1006,9 @@ void sha512_Init(SHA512_CTX* context) { j++ void sha512_Transform(const sha2_word64* state_in, const sha2_word64* data, sha2_word64* state_out) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, W512[16]; - int j; + sha2_word64 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; + sha2_word64 T1 = 0, W512[16] = {0}; + int j = 0; /* Initialize registers with the prev. intermediate value */ a = state_in[0]; @@ -1061,9 +1061,9 @@ void sha512_Transform(const sha2_word64* state_in, const sha2_word64* data, sha2 #else /* SHA2_UNROLL_TRANSFORM */ void sha512_Transform(const sha2_word64* state_in, const sha2_word64* data, sha2_word64* state_out) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, T2, W512[16]; - int j; + sha2_word64 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; + sha2_word64 T1 = 0, T2 = 0, W512[16] = {0}; + int j = 0; /* Initialize registers with the prev. intermediate value */ a = state_in[0]; @@ -1132,7 +1132,7 @@ void sha512_Transform(const sha2_word64* state_in, const sha2_word64* data, sha2 #endif /* SHA2_UNROLL_TRANSFORM */ void sha512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace, usedspace; + unsigned int freespace = 0, usedspace = 0; if (len == 0) { /* Calling with no data is valid - we do nothing */ @@ -1190,12 +1190,12 @@ void sha512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { } static void sha512_Last(SHA512_CTX* context) { - unsigned int usedspace; + unsigned int usedspace = 0; usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; /* Begin padding with a 1 bit: */ ((uint8_t*)context->buffer)[usedspace++] = 0x80; - + if (usedspace > SHA512_SHORT_BLOCK_LENGTH) { memzero(((uint8_t*)context->buffer) + usedspace, SHA512_BLOCK_LENGTH - usedspace); @@ -1248,8 +1248,8 @@ void sha512_Final(SHA512_CTX* context, sha2_byte digest[]) { } char *sha512_End(SHA512_CTX* context, char buffer[]) { - sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; - int i; + sha2_byte digest[SHA512_DIGEST_LENGTH] = {0}, *d = digest; + int i = 0; if (buffer != (char*)0) { sha512_Final(context, digest); @@ -1268,14 +1268,14 @@ char *sha512_End(SHA512_CTX* context, char buffer[]) { } void sha512_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA512_DIGEST_LENGTH]) { - SHA512_CTX context; + SHA512_CTX context = {0}; sha512_Init(&context); sha512_Update(&context, data, len); sha512_Final(&context, digest); } char* sha512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { - SHA512_CTX context; + SHA512_CTX context = {0}; sha512_Init(&context); sha512_Update(&context, data, len); diff --git a/Sources/VIZ/Base58.swift b/Sources/VIZ/Base58.swift deleted file mode 100644 index 74f8e27..0000000 --- a/Sources/VIZ/Base58.swift +++ /dev/null @@ -1,59 +0,0 @@ -/** - Base58 parser and encoder. - - author: Johan Nordberg - */ - -import Crypto -import Foundation - -internal extension Data { - /// Base58 encoding and decoding options. - struct Base58CheckOptions: OptionSet { - let rawValue: Int - /// Use graphene-style ripem160 checksum. - static let grapheneChecksum = Base58CheckOptions(rawValue: 1 << 0) - } - - /** - Creates a new data buffer from a Base58Check-encoded string. - - note: Returns nil if the check fails or if the string decodes to more than 128 bytes. - */ - init?(base58CheckEncoded str: String, options: Base58CheckOptions = []) { - let len = str.count - let data = UnsafeMutablePointer.allocate(capacity: len) - defer { data.deallocate() } - let res = str.withCString { (ptr: UnsafePointer) -> Int32 in - if options.contains(.grapheneChecksum) { - return base58gph_decode_check(ptr, data, Int32(len)) - } else { - return base58_decode_check(ptr, HASHER_SHA2D, data, Int32(len)) - } - } - guard res > 0 else { - return nil - } - self = Data(bytes: data, count: Int(res)) - } - - /** - Returns a Base58Check-encoded string. - - parameter graphene: Whether to encode with graphene-style ripem160 checksum or double-sha256. - - note: Returns nil for any data buffer larger than 128 bytes. - */ - func base58CheckEncodedString(options: Base58CheckOptions = []) -> String? { - let len = self.count * 2 - let str = UnsafeMutablePointer.allocate(capacity: len) - defer { str.deallocate() } - let res = self.withUnsafeBytes { (ptr: UnsafePointer) -> Int32 in - if options.contains(.grapheneChecksum) { - return base58gph_encode_check(ptr, Int32(self.count), str, Int32(len)) - } else { - return base58_encode_check(ptr, Int32(self.count), HASHER_SHA2D, str, Int32(len)) - } - } - guard res > 0 else { - return nil - } - return String(cString: str) - } -} diff --git a/Sources/VIZ/Extensions/Data+Base58Encoding.swift b/Sources/VIZ/Extensions/Data+Base58Encoding.swift new file mode 100644 index 0000000..eb20348 --- /dev/null +++ b/Sources/VIZ/Extensions/Data+Base58Encoding.swift @@ -0,0 +1,87 @@ +/// Base58 encoding and decoding extensions for the Data type. +/// - Author: Johan Nordberg + +import Crypto +import Foundation + +public extension Data { + /// Base58 encoding and decoding options. + enum Base58CheckType { + /// Use double-SHA256 checksum (Bitcoin-style). + case sha256d + /// Use RIPEMD160 checksum (Graphehe-style). + case ripemd160 + /// Use RIPEMD160 checksum with extra suffix (EOSIO-style). + case ripemd160Extra(_ extra: Data) + } + + /// Calculate checksum for data using given checksum type. + private static func checksum(for data: Data, using checksumType: Base58CheckType) -> Data { + let digest: Data + switch checksumType { + case .sha256d: + digest = data.sha256Digest.sha256Digest + case .ripemd160: + digest = data.ripemd160Digest + case let .ripemd160Extra(extra): + digest = (data + extra).ripemd160Digest + } + return digest.prefix(4) + } + + /// Creates a new data buffer from a Base58Check-encoded string. + /// - Parameter checksumType: Checksum to use when decoding data, defaults to the standard double-sha256. + /// - Note: Returns `nil` if decoding or the check fails. + init?(base58CheckEncoded str: String, _ checksumType: Base58CheckType = .sha256d) { + guard let decoded = Data(base58Encoded: str), decoded.count > 4 else { + return nil + } + let data = decoded.prefix(decoded.count - 4) + let checksum = decoded.suffix(4) + guard Self.checksum(for: data, using: checksumType) == checksum else { + return nil + } + self = data + } + + /// Creates a new data buffer from a Base58-encoded string. + /// - Note: Returns `nil` if decoding fails. + init?(base58Encoded str: String) { + let len: size_t = str.lengthOfBytes(using: .utf8) + let data = UnsafeMutablePointer.allocate(capacity: len) + defer { data.deallocate() } + let res = str.withCString { str -> Int in + base58_decode(str, data, len) + } + guard res > 0 else { + return nil + } + self = Data(bytes: data, count: res) + } + + /// Returns a Base58Check-encoded string. + /// - Parameter options: Options to use when encoding string. + /// - Note: Returns `nil` if data buffer is empty or null.. + func base58CheckEncodedString(_ checksumType: Base58CheckType = .sha256d) -> String? { + return (self + Self.checksum(for: self, using: checksumType)).base58EncodedString() + } + + /// Encode data into base58 format. + /// - Returns: Base58-encoded string or `nil` if encoding fails. + /// - Note: Returns `nil` if data buffer is empty or larger than 4kb. + func base58EncodedString() -> String? { + let strsize = self.count * 2 + let str = UnsafeMutablePointer.allocate(capacity: strsize) + defer { str.deallocate() } + let res = self.withUnsafeBytes { ptr -> Int in + guard !ptr.isEmpty, ptr.count <= 4000 else { + return 0 + } + return base58_encode(ptr.bufPtr, ptr.count, str, strsize) + } + guard res > 0 else { + return nil + } + return String(cString: str) + } +} diff --git a/Sources/VIZ/Extensions/Data+RIPEMD160.swift b/Sources/VIZ/Extensions/Data+RIPEMD160.swift new file mode 100644 index 0000000..9b2403f --- /dev/null +++ b/Sources/VIZ/Extensions/Data+RIPEMD160.swift @@ -0,0 +1,20 @@ +/// RIPEMD160 hash extension for the Data type. +/// - Author: Johan Nordberg + +import Crypto +import Foundation + +public extension Data { + var ripemd160Digest: Data { + var rv = Data(repeating: 0, count: Int(RIPEMD160_DIGEST_LENGTH)) + self.withUnsafeBytes { msg in + guard msg.baseAddress != nil else { + return + } + rv.withUnsafeMutableBytes { hash -> Void in + ripemd160(msg.bufPtr, UInt32(msg.count), hash.bufPtr) + } + } + return rv + } +} diff --git a/Sources/VIZ/Extensions/Data+SHA2.swift b/Sources/VIZ/Extensions/Data+SHA2.swift new file mode 100644 index 0000000..0adfabb --- /dev/null +++ b/Sources/VIZ/Extensions/Data+SHA2.swift @@ -0,0 +1,35 @@ +/// SHA2 hash extension for the Data type. +/// - Author: Johan Nordberg + +import Crypto +import Foundation + +public extension Data { + /// 32-byte SHA-256 digest of data. + var sha256Digest: Data { + var rv = Data(repeating: 0, count: Int(SHA256_DIGEST_LENGTH)) + self.withUnsafeBytes { msg in + guard msg.baseAddress != nil else { + return + } + rv.withUnsafeMutableBytes { hash -> Void in + sha256_Raw(msg.bufPtr, msg.count, hash.bufPtr) + } + } + return rv + } + + /// 64-byte SHA-512 digest of data. + var sha512Digest: Data { + var rv = Data(repeating: 0, count: Int(SHA512_DIGEST_LENGTH)) + self.withUnsafeBytes { msg in + guard msg.baseAddress != nil else { + return + } + rv.withUnsafeMutableBytes { hash -> Void in + sha512_Raw(msg.bufPtr, msg.count, hash.bufPtr) + } + } + return rv + } +} diff --git a/Sources/VIZ/PrivateKey.swift b/Sources/VIZ/PrivateKey.swift index aae147d..3885933 100644 --- a/Sources/VIZ/PrivateKey.swift +++ b/Sources/VIZ/PrivateKey.swift @@ -38,7 +38,7 @@ public struct PrivateKey: Equatable { guard let data = seed.data(using: .utf8) else { return nil } - self.secret = data.sha256Digest() + self.secret = data.sha256Digest } /// Sign a message. @@ -50,7 +50,7 @@ public struct PrivateKey: Equatable { if PrivateKey.determenisticSignatures { ndata[0] += 1 } else { - ndata = Random.bytes(count: 32) + ndata = Data.random(32) } result = try Secp256k1.shared.sign(message: message, secretKey: self.secret, ndata: ndata) } while (!isCanonicalSignature(result.0)) diff --git a/Sources/VIZ/PublicKey.swift b/Sources/VIZ/PublicKey.swift index ccab63a..a3d0914 100644 --- a/Sources/VIZ/PublicKey.swift +++ b/Sources/VIZ/PublicKey.swift @@ -40,7 +40,7 @@ public struct PublicKey: Equatable { guard key.count > 0 else { return nil } - guard let keyData = Data(base58CheckEncoded: String(key), options: .grapheneChecksum) else { + guard let keyData = Data(base58CheckEncoded: String(key), .ripemd160) else { return nil } self.prefix = AddressPrefix(String(prefix)) @@ -49,7 +49,7 @@ public struct PublicKey: Equatable { /// Public key address string. public var address: String { - return String(self.prefix) + self.key.base58CheckEncodedString(options: .grapheneChecksum)! + return String(self.prefix) + self.key.base58CheckEncodedString(.ripemd160)! } } diff --git a/Sources/VIZ/Random.swift b/Sources/VIZ/Random.swift deleted file mode 100644 index c9438d7..0000000 --- a/Sources/VIZ/Random.swift +++ /dev/null @@ -1,39 +0,0 @@ -/// Cryptographically secure random number generation. -/// - Author: Johan Nordberg - -import Foundation - -#if !os(Linux) - import Security -#else - import Glibc -#endif - -/// A cryptographically secure number random generator. -internal struct Random { - /// Get random bytes. - /// - Parameter count: How many bytes to generate. - static func bytes(count: Int) -> Data { - var rv = Data(count: count) - #if os(Linux) - guard let file = fopen("/dev/urandom", "r") else { - fatalError("Unable to open /dev/urandom for reading.") - } - defer { fclose(file) } - let bytesRead = rv.withUnsafeMutableBytes { - fread($0, 1, count, file) - } - guard bytesRead == count else { - fatalError("Unable to read from /dev/urandom.") - } - #else - let result = rv.withUnsafeMutableBytes { - SecRandomCopyBytes(kSecRandomDefault, count, $0) - } - guard result == errSecSuccess else { - fatalError("Unable to generate random data.") - } - #endif - return rv - } -} diff --git a/Sources/VIZ/Sha2.swift b/Sources/VIZ/Sha2.swift deleted file mode 100644 index 478215e..0000000 --- a/Sources/VIZ/Sha2.swift +++ /dev/null @@ -1,18 +0,0 @@ -/// Sha2 bindings. -/// - Author: Johan Nordberg - -import Crypto -import Foundation - -internal extension Data { - /// Return a SHA2-256 hash of the data. - func sha256Digest() -> Data { - let buf = UnsafeMutablePointer.allocate(capacity: 32) - self.withUnsafeBytes { - hasher_Raw(HASHER_SHA2, $0, self.count, buf) - } - return Data(bytesNoCopy: buf, count: 32, deallocator: .custom({ ptr, _ in - ptr.deallocate() - })) - } -} diff --git a/Sources/VIZ/Transaction.swift b/Sources/VIZ/Transaction.swift index abb7dd3..f427df6 100644 --- a/Sources/VIZ/Transaction.swift +++ b/Sources/VIZ/Transaction.swift @@ -55,8 +55,7 @@ public struct Transaction: _Transaction { public func digest(forChain chain: ChainId = .mainNet) throws -> Data { var data = chain.data data.append(try VIZEncoder.encode(self)) -// print(data.hexEncodedString()) - return data.sha256Digest() + return data.sha256Digest } } diff --git a/Tests/UnitTests/Base58.swift b/Tests/UnitTests/Base58.swift index 8c29b45..aba1b15 100644 --- a/Tests/UnitTests/Base58.swift +++ b/Tests/UnitTests/Base58.swift @@ -63,17 +63,17 @@ let base64_base58_pairs = [ class Base58Test: XCTestCase { func testDecode() { for (b64, b58, graphene) in base64_base58_pairs { - let options: Data.Base58CheckOptions = graphene ? [.grapheneChecksum] : [] - let data = Data(base58CheckEncoded: b58, options: options) + let options: Data.Base58CheckType = graphene ? .ripemd160 : .sha256d + let data = Data(base58CheckEncoded: b58, options) XCTAssertEqual(data?.base64EncodedString(), b64) } } func testEncode() { for (b64, b58, graphene) in base64_base58_pairs { - let options: Data.Base58CheckOptions = graphene ? [.grapheneChecksum] : [] + let options: Data.Base58CheckType = graphene ? .ripemd160 : .sha256d let data = Data(base64Encoded: b64)! - XCTAssertEqual(data.base58CheckEncodedString(options: options), b58) + XCTAssertEqual(data.base58CheckEncodedString(options), b58) } } } diff --git a/Tests/UnitTests/Sha2.swift b/Tests/UnitTests/Sha2.swift index cc5be89..31cd9ec 100644 --- a/Tests/UnitTests/Sha2.swift +++ b/Tests/UnitTests/Sha2.swift @@ -4,6 +4,6 @@ import XCTest class Sha2Test: XCTestCase { func testDigest() { let data = Data(base64Encoded: "A4fYIELZNEcAjf4q92IGih5T/zlKW/j2igRfpkK5nqXR")! - XCTAssertEqual(data.sha256Digest(), Data(base64Encoded: "nxseRPD/eP7rVE0ceWhzRvPNyfbiNlPKKuS6f+6cHUY=")) + XCTAssertEqual(data.sha256Digest, Data(base64Encoded: "nxseRPD/eP7rVE0ceWhzRvPNyfbiNlPKKuS6f+6cHUY=")) } }