| 'use strict'; |
| |
| var BN = require('bn.js'); |
| var utils = require('../utils'); |
| var assert = utils.assert; |
| var cachedProperty = utils.cachedProperty; |
| var parseBytes = utils.parseBytes; |
| |
| /** |
| * @param {EDDSA} eddsa - eddsa instance |
| * @param {Array<Bytes>|Object} sig - |
| * @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes |
| * @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes |
| * @param {Array<Bytes>} [sig.Rencoded] - R point encoded |
| * @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded |
| */ |
| function Signature(eddsa, sig) { |
| this.eddsa = eddsa; |
| |
| if (typeof sig !== 'object') |
| sig = parseBytes(sig); |
| |
| if (Array.isArray(sig)) { |
| sig = { |
| R: sig.slice(0, eddsa.encodingLength), |
| S: sig.slice(eddsa.encodingLength) |
| }; |
| } |
| |
| assert(sig.R && sig.S, 'Signature without R or S'); |
| |
| if (eddsa.isPoint(sig.R)) |
| this._R = sig.R; |
| if (sig.S instanceof BN) |
| this._S = sig.S; |
| |
| this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded; |
| this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded; |
| } |
| |
| cachedProperty(Signature, 'S', function S() { |
| return this.eddsa.decodeInt(this.Sencoded()); |
| }); |
| |
| cachedProperty(Signature, 'R', function R() { |
| return this.eddsa.decodePoint(this.Rencoded()); |
| }); |
| |
| cachedProperty(Signature, 'Rencoded', function Rencoded() { |
| return this.eddsa.encodePoint(this.R()); |
| }); |
| |
| cachedProperty(Signature, 'Sencoded', function Sencoded() { |
| return this.eddsa.encodeInt(this.S()); |
| }); |
| |
| Signature.prototype.toBytes = function toBytes() { |
| return this.Rencoded().concat(this.Sencoded()); |
| }; |
| |
| Signature.prototype.toHex = function toHex() { |
| return utils.encode(this.toBytes(), 'hex').toUpperCase(); |
| }; |
| |
| module.exports = Signature; |