Beispiel #1
0
func writeBigInt(value *big.Int, buffer *bytes.Buffer, cutoff *big.Int) (positive bool) {
	if value.IsZero() {
		buffer.Write(zeroBase)
		return !value.RawNeg()
	}
	if !value.RawNeg() {
		positive = true
		if value.Cmp(cutoff) == -1 {
			encoding := []byte{'\x80', '\x01', '\x01'}
			mod := big.NewInt(0)
			div, mod := value.DivMod(value, bigint255, mod)
			encoding[2] = byte(mod.Int64()) + 1
			if div.Sign() == 1 {
				div, mod = div.DivMod(div, bigint255, mod)
				encoding[1] = byte(mod.Int64()) + 1
				if div.Sign() == 1 {
					encoding[0] = byte(div.Int64()) + 128
				}
			}
			buffer.Write(encoding)
		} else {
			value = value.Sub(value, cutoff)
			buffer.WriteByte('\xff')
			left := big.NewInt(0)
			lead, left := value.DivMod(value, bigint255, left)
			var n int64 = 1
			exp := big.NewInt(0)
			div := big.NewInt(0)
			for (div.Div(lead, exp.Exp(big.NewInt(253), big.NewInt(n), nil))).Sign() == 1 {
				n += 1
			}
			buffer.WriteByte(byte(n) + 1)
			buffer.WriteByte('\xff')
			leadChars := make([]byte, 0)
			mod := big.NewInt(0)
			for {
				if lead.IsZero() {
					break
				}
				lead, mod = lead.DivMod(lead, bigint253, mod)
				leadChars = append(leadChars, byte(mod.Int64())+2)
			}
			lenLead := len(leadChars)
			if lenLead > 0 {
				for i := lenLead - 1; i >= 0; i-- {
					buffer.WriteByte(leadChars[i])
				}
			}
			if left.Sign() == 1 {
				buffer.WriteByte('\x01')
				buffer.WriteByte(byte(left.Int64()))
			}
		}
	} else {
		value = value.Neg(value)
		if value.Cmp(cutoff) == -1 {
			encoding := []byte{'\x7f', '\xfe', '\xfe'}
			mod := big.NewInt(0)
			div, mod := value.DivMod(value, bigint255, mod)
			encoding[2] = 254 - byte(mod.Int64())
			if div.Sign() == 1 {
				div, mod = div.DivMod(div, bigint255, mod)
				encoding[1] = 254 - byte(mod.Int64())
				if div.Sign() == 1 {
					encoding[0] = 127 - byte(div.Int64())
				}
			}
			buffer.Write(encoding)
		} else {
			value = value.Sub(value, cutoff)
			buffer.WriteByte('\x00')
			left := big.NewInt(0)
			lead, left := value.DivMod(value, bigint254, left)
			var n int64 = 1
			exp := big.NewInt(0)
			div := big.NewInt(0)
			for (div.Div(lead, exp.Exp(big.NewInt(253), big.NewInt(n), nil))).Sign() == 1 {
				n += 1
			}
			buffer.WriteByte(254 - byte(n))
			buffer.WriteByte('\x00')
			leadChars := make([]byte, 0)
			mod := big.NewInt(0)
			for {
				if lead.IsZero() {
					break
				}
				lead, mod = lead.DivMod(lead, bigint253, mod)
				leadChars = append(leadChars, byte(253-mod.Int64()))
			}
			lenLead := len(leadChars)
			if lenLead > 0 {
				for i := lenLead - 1; i >= 0; i-- {
					buffer.WriteByte(leadChars[i])
				}
			}
			if lenLead > 1 {
				buffer.WriteByte('\x00')
			}
			buffer.WriteByte('\xfe')
			if left.Sign() == 1 {
				buffer.WriteByte('\x01')
				buffer.WriteByte(254 - byte(left.Int64()))
			} else {
				buffer.WriteByte('\xfe')
			}
		}
	}
	return
}
Beispiel #2
0
func encodeBigInt(value *big.Int, cutoff *big.Int) []byte {
	if value.IsZero() {
		return []byte{'\x80', '\x01', '\x01'}
	}
	if !value.IsNegative() {
		if value.Cmp(cutoff) == -1 {
			encoding := []byte{'\x80', '\x01', '\x01'}
			mod := big.NewInt(0)
			div, mod := value.DivMod(value, bigint255, mod)
			encoding[2] = byte(mod.Int64()) + 1
			if div.Sign() == 1 {
				div, mod = div.DivMod(div, bigint255, mod)
				encoding[1] = byte(mod.Int64()) + 1
				if div.Sign() == 1 {
					encoding[0] = byte(div.Int64()) + 128
				}
			}
			return encoding
		}
		value = value.Sub(value, cutoff)
		encoding := []byte{'\xff'}
		left := big.NewInt(0)
		lead, left := value.DivMod(value, bigint255, left)
		var n int64 = 1
		exp := big.NewInt(0)
		div := big.NewInt(0)
		for (div.Div(lead, exp.Exp(big.NewInt(253), big.NewInt(n), nil))).Sign() == 1 {
			n += 1
		}
		encoding = append(encoding, byte(n)+1, '\xff')
		leadChars := make([]byte, 0)
		mod := big.NewInt(0)
		for {
			if lead.IsZero() {
				break
			}
			lead, mod = lead.DivMod(lead, bigint253, mod)
			leadChars = append(leadChars, byte(mod.Int64())+2)
		}
		lenLead := len(leadChars)
		if lenLead > 0 {
			for i := lenLead - 1; i >= 0; i-- {
				encoding = append(encoding, leadChars[i])
			}
		}
		if left.Sign() == 1 {
			encoding = append(encoding, '\x01', byte(left.Int64()))
		}
		return encoding
	}
	value = value.Neg(value)
	if value.Cmp(cutoff) == -1 {
		encoding := []byte{'\x7f', '\xfe', '\xfe'}
		mod := big.NewInt(0)
		div, mod := value.DivMod(value, bigint255, mod)
		encoding[2] = 254 - byte(mod.Int64())
		if div.Sign() == 1 {
			div, mod = div.DivMod(div, bigint255, mod)
			encoding[1] = 254 - byte(mod.Int64())
			if div.Sign() == 1 {
				encoding[0] = 127 - byte(div.Int64())
			}
		}
		return encoding
	}
	value = value.Sub(value, cutoff)
	encoding := []byte{'\x00'}
	left := big.NewInt(0)
	lead, left := value.DivMod(value, bigint254, left)
	var n int64 = 1
	exp := big.NewInt(0)
	div := big.NewInt(0)
	for (div.Div(lead, exp.Exp(big.NewInt(253), big.NewInt(n), nil))).Sign() == 1 {
		n += 1
	}
	encoding = append(encoding, 254-byte(n), '\x00')
	leadChars := make([]byte, 0)
	mod := big.NewInt(0)
	for {
		if lead.IsZero() {
			break
		}
		lead, mod = lead.DivMod(lead, bigint253, mod)
		leadChars = append(leadChars, byte(253-mod.Int64()))
	}
	lenLead := len(leadChars)
	if lenLead > 0 {
		for i := lenLead - 1; i >= 0; i-- {
			encoding = append(encoding, leadChars[i])
		}
	}
	if lenLead > 1 {
		encoding = append(encoding, '\x00')
	}
	encoding = append(encoding, '\xfe')
	if left.Sign() == 1 {
		encoding = append(encoding, '\x01', 254-byte(left.Int64()))
	} else {
		encoding = append(encoding, '\xfe')
	}
	return encoding
}