weierstrass.d.ts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
  2. import { AffinePoint, BasicCurve, Group, GroupConstructor } from './curve.js';
  3. import * as mod from './modular.js';
  4. import { CHash, Hex, PrivKey } from './utils.js';
  5. export type { AffinePoint };
  6. type HmacFnSync = (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
  7. type EndomorphismOpts = {
  8. beta: bigint;
  9. splitScalar: (k: bigint) => {
  10. k1neg: boolean;
  11. k1: bigint;
  12. k2neg: boolean;
  13. k2: bigint;
  14. };
  15. };
  16. export type BasicWCurve<T> = BasicCurve<T> & {
  17. a: T;
  18. b: T;
  19. allowedPrivateKeyLengths?: readonly number[];
  20. wrapPrivateKey?: boolean;
  21. endo?: EndomorphismOpts;
  22. isTorsionFree?: (c: ProjConstructor<T>, point: ProjPointType<T>) => boolean;
  23. clearCofactor?: (c: ProjConstructor<T>, point: ProjPointType<T>) => ProjPointType<T>;
  24. };
  25. type Entropy = Hex | boolean;
  26. export type SignOpts = {
  27. lowS?: boolean;
  28. extraEntropy?: Entropy;
  29. prehash?: boolean;
  30. };
  31. export type VerOpts = {
  32. lowS?: boolean;
  33. prehash?: boolean;
  34. };
  35. /**
  36. * ### Design rationale for types
  37. *
  38. * * Interaction between classes from different curves should fail:
  39. * `k256.Point.BASE.add(p256.Point.BASE)`
  40. * * For this purpose we want to use `instanceof` operator, which is fast and works during runtime
  41. * * Different calls of `curve()` would return different classes -
  42. * `curve(params) !== curve(params)`: if somebody decided to monkey-patch their curve,
  43. * it won't affect others
  44. *
  45. * TypeScript can't infer types for classes created inside a function. Classes is one instance of nominative types in TypeScript and interfaces only check for shape, so it's hard to create unique type for every function call.
  46. *
  47. * We can use generic types via some param, like curve opts, but that would:
  48. * 1. Enable interaction between `curve(params)` and `curve(params)` (curves of same params)
  49. * which is hard to debug.
  50. * 2. Params can be generic and we can't enforce them to be constant value:
  51. * if somebody creates curve from non-constant params,
  52. * it would be allowed to interact with other curves with non-constant params
  53. *
  54. * TODO: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol
  55. */
  56. export interface ProjPointType<T> extends Group<ProjPointType<T>> {
  57. readonly px: T;
  58. readonly py: T;
  59. readonly pz: T;
  60. get x(): T;
  61. get y(): T;
  62. multiply(scalar: bigint): ProjPointType<T>;
  63. toAffine(iz?: T): AffinePoint<T>;
  64. isTorsionFree(): boolean;
  65. clearCofactor(): ProjPointType<T>;
  66. assertValidity(): void;
  67. hasEvenY(): boolean;
  68. toRawBytes(isCompressed?: boolean): Uint8Array;
  69. toHex(isCompressed?: boolean): string;
  70. multiplyUnsafe(scalar: bigint): ProjPointType<T>;
  71. multiplyAndAddUnsafe(Q: ProjPointType<T>, a: bigint, b: bigint): ProjPointType<T> | undefined;
  72. _setWindowSize(windowSize: number): void;
  73. }
  74. export interface ProjConstructor<T> extends GroupConstructor<ProjPointType<T>> {
  75. new (x: T, y: T, z: T): ProjPointType<T>;
  76. fromAffine(p: AffinePoint<T>): ProjPointType<T>;
  77. fromHex(hex: Hex): ProjPointType<T>;
  78. fromPrivateKey(privateKey: PrivKey): ProjPointType<T>;
  79. normalizeZ(points: ProjPointType<T>[]): ProjPointType<T>[];
  80. }
  81. export type CurvePointsType<T> = BasicWCurve<T> & {
  82. fromBytes?: (bytes: Uint8Array) => AffinePoint<T>;
  83. toBytes?: (c: ProjConstructor<T>, point: ProjPointType<T>, isCompressed: boolean) => Uint8Array;
  84. };
  85. declare function validatePointOpts<T>(curve: CurvePointsType<T>): Readonly<{
  86. readonly nBitLength: number;
  87. readonly nByteLength: number;
  88. readonly Fp: mod.IField<T>;
  89. readonly n: bigint;
  90. readonly h: bigint;
  91. readonly hEff?: bigint;
  92. readonly Gx: T;
  93. readonly Gy: T;
  94. readonly allowInfinityPoint?: boolean;
  95. readonly a: T;
  96. readonly b: T;
  97. readonly allowedPrivateKeyLengths?: readonly number[];
  98. readonly wrapPrivateKey?: boolean;
  99. readonly endo?: EndomorphismOpts;
  100. readonly isTorsionFree?: ((c: ProjConstructor<T>, point: ProjPointType<T>) => boolean) | undefined;
  101. readonly clearCofactor?: ((c: ProjConstructor<T>, point: ProjPointType<T>) => ProjPointType<T>) | undefined;
  102. readonly fromBytes?: ((bytes: Uint8Array) => AffinePoint<T>) | undefined;
  103. readonly toBytes?: ((c: ProjConstructor<T>, point: ProjPointType<T>, isCompressed: boolean) => Uint8Array) | undefined;
  104. readonly p: bigint;
  105. }>;
  106. export type CurvePointsRes<T> = {
  107. CURVE: ReturnType<typeof validatePointOpts<T>>;
  108. ProjectivePoint: ProjConstructor<T>;
  109. normPrivateKeyToScalar: (key: PrivKey) => bigint;
  110. weierstrassEquation: (x: T) => T;
  111. isWithinCurveOrder: (num: bigint) => boolean;
  112. };
  113. export declare const DER: {
  114. Err: {
  115. new (m?: string): {
  116. name: string;
  117. message: string;
  118. stack?: string;
  119. };
  120. };
  121. _parseInt(data: Uint8Array): {
  122. d: bigint;
  123. l: Uint8Array;
  124. };
  125. toSig(hex: string | Uint8Array): {
  126. r: bigint;
  127. s: bigint;
  128. };
  129. hexFromSig(sig: {
  130. r: bigint;
  131. s: bigint;
  132. }): string;
  133. };
  134. export declare function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T>;
  135. export interface SignatureType {
  136. readonly r: bigint;
  137. readonly s: bigint;
  138. readonly recovery?: number;
  139. assertValidity(): void;
  140. addRecoveryBit(recovery: number): RecoveredSignatureType;
  141. hasHighS(): boolean;
  142. normalizeS(): SignatureType;
  143. recoverPublicKey(msgHash: Hex): ProjPointType<bigint>;
  144. toCompactRawBytes(): Uint8Array;
  145. toCompactHex(): string;
  146. toDERRawBytes(isCompressed?: boolean): Uint8Array;
  147. toDERHex(isCompressed?: boolean): string;
  148. }
  149. export type RecoveredSignatureType = SignatureType & {
  150. readonly recovery: number;
  151. };
  152. export type SignatureConstructor = {
  153. new (r: bigint, s: bigint): SignatureType;
  154. fromCompact(hex: Hex): SignatureType;
  155. fromDER(hex: Hex): SignatureType;
  156. };
  157. type SignatureLike = {
  158. r: bigint;
  159. s: bigint;
  160. };
  161. export type PubKey = Hex | ProjPointType<bigint>;
  162. export type CurveType = BasicWCurve<bigint> & {
  163. hash: CHash;
  164. hmac: HmacFnSync;
  165. randomBytes: (bytesLength?: number) => Uint8Array;
  166. lowS?: boolean;
  167. bits2int?: (bytes: Uint8Array) => bigint;
  168. bits2int_modN?: (bytes: Uint8Array) => bigint;
  169. };
  170. declare function validateOpts(curve: CurveType): Readonly<{
  171. readonly nBitLength: number;
  172. readonly nByteLength: number;
  173. readonly Fp: mod.IField<bigint>;
  174. readonly n: bigint;
  175. readonly h: bigint;
  176. readonly hEff?: bigint;
  177. readonly Gx: bigint;
  178. readonly Gy: bigint;
  179. readonly allowInfinityPoint?: boolean;
  180. readonly a: bigint;
  181. readonly b: bigint;
  182. readonly allowedPrivateKeyLengths?: readonly number[];
  183. readonly wrapPrivateKey?: boolean;
  184. readonly endo?: EndomorphismOpts;
  185. readonly isTorsionFree?: ((c: ProjConstructor<bigint>, point: ProjPointType<bigint>) => boolean) | undefined;
  186. readonly clearCofactor?: ((c: ProjConstructor<bigint>, point: ProjPointType<bigint>) => ProjPointType<bigint>) | undefined;
  187. readonly hash: CHash;
  188. readonly hmac: HmacFnSync;
  189. readonly randomBytes: (bytesLength?: number) => Uint8Array;
  190. lowS: boolean;
  191. readonly bits2int?: (bytes: Uint8Array) => bigint;
  192. readonly bits2int_modN?: (bytes: Uint8Array) => bigint;
  193. readonly p: bigint;
  194. }>;
  195. export type CurveFn = {
  196. CURVE: ReturnType<typeof validateOpts>;
  197. getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;
  198. getSharedSecret: (privateA: PrivKey, publicB: Hex, isCompressed?: boolean) => Uint8Array;
  199. sign: (msgHash: Hex, privKey: PrivKey, opts?: SignOpts) => RecoveredSignatureType;
  200. verify: (signature: Hex | SignatureLike, msgHash: Hex, publicKey: Hex, opts?: VerOpts) => boolean;
  201. ProjectivePoint: ProjConstructor<bigint>;
  202. Signature: SignatureConstructor;
  203. utils: {
  204. normPrivateKeyToScalar: (key: PrivKey) => bigint;
  205. isValidPrivateKey(privateKey: PrivKey): boolean;
  206. randomPrivateKey: () => Uint8Array;
  207. precompute: (windowSize?: number, point?: ProjPointType<bigint>) => ProjPointType<bigint>;
  208. };
  209. };
  210. export declare function weierstrass(curveDef: CurveType): CurveFn;
  211. /**
  212. * Implementation of the Shallue and van de Woestijne method for any weierstrass curve.
  213. * TODO: check if there is a way to merge this with uvRatio in Edwards; move to modular.
  214. * b = True and y = sqrt(u / v) if (u / v) is square in F, and
  215. * b = False and y = sqrt(Z * (u / v)) otherwise.
  216. * @param Fp
  217. * @param Z
  218. * @returns
  219. */
  220. export declare function SWUFpSqrtRatio<T>(Fp: mod.IField<T>, Z: T): (u: T, v: T) => {
  221. isValid: boolean;
  222. value: T;
  223. };
  224. /**
  225. * Simplified Shallue-van de Woestijne-Ulas Method
  226. * https://www.rfc-editor.org/rfc/rfc9380#section-6.6.2
  227. */
  228. export declare function mapToCurveSimpleSWU<T>(Fp: mod.IField<T>, opts: {
  229. A: T;
  230. B: T;
  231. Z: T;
  232. }): (u: T) => {
  233. x: T;
  234. y: T;
  235. };
  236. //# sourceMappingURL=weierstrass.d.ts.map