From 628300f9d61cf42f40cc69620f6c93a12fcad3b6 Mon Sep 17 00:00:00 2001 From: Alexis Hernandez Date: Sat, 16 Mar 2019 18:01:51 -0700 Subject: [PATCH] server: Add the gcs SipHashKey --- .../app/com/xsn/explorer/gcs/SipHashKey.scala | 32 +++++++++++++++++++ server/app/com/xsn/explorer/gcs/package.scala | 9 ++++++ .../com/xsn/explorer/gcs/SipHashKeySpec.scala | 19 +++++++++++ 3 files changed, 60 insertions(+) create mode 100644 server/app/com/xsn/explorer/gcs/SipHashKey.scala create mode 100644 server/app/com/xsn/explorer/gcs/package.scala create mode 100644 server/test/com/xsn/explorer/gcs/SipHashKeySpec.scala diff --git a/server/app/com/xsn/explorer/gcs/SipHashKey.scala b/server/app/com/xsn/explorer/gcs/SipHashKey.scala new file mode 100644 index 0000000..da04aa5 --- /dev/null +++ b/server/app/com/xsn/explorer/gcs/SipHashKey.scala @@ -0,0 +1,32 @@ +package com.xsn.explorer.gcs + +import com.google.common.primitives.Longs + +/** + * Represents a SipHash key using a 128-bit value, compatible with Guava. + * + * @param k0 the first half of the key + * @param k1 the second half of the key + */ +case class SipHashKey(k0: Long, k1: Long) + +object SipHashKey { + + /** + * Parses a SipHash key in the same way that the Btcutil (https://github.com/btcsuite/btcutil) + * library does, which uses https://github.com/aead/siphash + * + * @param key 16 bytes representing the key + */ + def fromBtcutil(key: List[Byte]): SipHashKey = { + require(key.size == 16, "Invalid SipHash key, it must have 16 bytes") + + /** + * the bytes are represented as a 128-bit encoded in little-endian + * while guava parses the values in big-endian, that's the reason to reverse them. + */ + val k0 = Longs.fromByteArray(key.take(8).reverse.toArray) + val k1 = Longs.fromByteArray(key.drop(8).reverse.toArray) + SipHashKey(k0, k1) + } +} diff --git a/server/app/com/xsn/explorer/gcs/package.scala b/server/app/com/xsn/explorer/gcs/package.scala new file mode 100644 index 0000000..2ed1850 --- /dev/null +++ b/server/app/com/xsn/explorer/gcs/package.scala @@ -0,0 +1,9 @@ +package com.xsn.explorer + +/** + * The package does similar operations for Golomb-Coded Sets similar to what + * the Btcutil library does (https://github.com/btcsuite/btcutil/tree/master/gcs). + * + * Everything is based on https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki + */ +package object gcs diff --git a/server/test/com/xsn/explorer/gcs/SipHashKeySpec.scala b/server/test/com/xsn/explorer/gcs/SipHashKeySpec.scala new file mode 100644 index 0000000..e4c317c --- /dev/null +++ b/server/test/com/xsn/explorer/gcs/SipHashKeySpec.scala @@ -0,0 +1,19 @@ +package com.xsn.explorer.gcs + +import org.scalatest.MustMatchers._ +import org.scalatest.WordSpec + +class SipHashKeySpec extends WordSpec { + + "parsing a Btcutil-like key" should { + "parse the right values" in { + val bytes = List( + 0x4c, 0xb1, 0xab, 0x12, 0x57, 0x62, 0x1e, 0x41, + 0x3b, 0x8b, 0x0e, 0x26, 0x64, 0x8d, 0x4a, 0x15).map(_.asInstanceOf[Byte]) + + val key = SipHashKey.fromBtcutil(bytes) + key.k0 must be(4692295987881554252L) + key.k1 must be(1534194084347808571l) + } + } +}