TLSHDigest8.java

  1. /*
  2.  * Copyright 2020 Keve Müller
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *     http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. package app.keve.ktlsh.impl;

  17. import java.nio.ByteBuffer;

  18. /**
  19.  * A TLSH digester for window size of 8 bytes.
  20.  *
  21.  * @author keve
  22.  *
  23.  */
  24. public final class TLSHDigest8 extends AbstractTLSHDigest {
  25.     /**
  26.      * The supported window length.
  27.      */
  28.     public static final int WINDOW_LENGTH = 8;
  29.     /**
  30.      * Hold the lag window of 7 bytes.
  31.      */
  32.     private long lag;

  33.     /**
  34.      * Construct the instance with window length 8.
  35.      *
  36.      * @param bucketCount    the number of buckets (128|256)
  37.      * @param checkSumLength the number of checksum bytes (1|3)
  38.      */
  39.     public TLSHDigest8(final int bucketCount, final int checkSumLength) {
  40.         super(WINDOW_LENGTH, bucketCount, checkSumLength);
  41.     }

  42.     @Override
  43.     public void update(final ByteBuffer buf) {
  44.         int l1 = (int) (lag & 0xFF);
  45.         int l2 = (int) (lag >>> 8 & 0xFF);
  46.         int l3 = (int) (lag >>> 16 & 0xFF);
  47.         int l4 = (int) (lag >>> 24 & 0xFF);
  48.         int l5 = (int) (lag >>> 32 & 0xFF);
  49.         int l6 = (int) (lag >>> 40 & 0xFF);
  50.         int l7 = (int) (lag >>> 48 & 0xFF);
  51.         while (buf.hasRemaining()) {
  52.             final int l0 = buf.get() & 0xFF;
  53.             count++;
  54.             if (count >= windowLength) {
  55.                 switch (checkSumLength) {
  56.                 case 1:
  57.                     checksum[0] = sMapping(T0, l0, l1, checksum[0]);
  58.                     break;
  59.                 case 3:
  60.                     checksum[0] = sMapping(T0, l0, l1, checksum[0]);
  61.                     checksum[1] = bMapping(checksum[0], l0, l1, checksum[1]);
  62.                     checksum[2] = bMapping(checksum[1], l0, l1, checksum[2]);
  63.                     break;
  64.                 default:
  65. //                    checksum[0] = sMapping(T0, l0, l1, checksum[0]);
  66. //                    for (int k = 1; k < checksum.length; k++) {
  67. //                        checksum[k] = bMapping(checksum[k - 1], l0, l1, checksum[k]);
  68. //                    }
  69. //                    break;
  70.                     throw new IllegalArgumentException("impossible");
  71.                 }

  72.                 aBucket[sMapping(T2, l0, l1, l2)]++;
  73.                 aBucket[sMapping(T3, l0, l1, l3)]++;
  74.                 aBucket[sMapping(T5, l0, l2, l3)]++;

  75.                 aBucket[sMapping(T7, l0, l2, l4)]++;
  76.                 aBucket[sMapping(T11, l0, l1, l4)]++;
  77.                 aBucket[sMapping(T13, l0, l3, l4)]++;

  78.                 aBucket[sMapping(T17, l0, l1, l5)]++;
  79.                 aBucket[sMapping(T19, l0, l2, l5)]++;
  80.                 aBucket[sMapping(T23, l0, l3, l5)]++;
  81.                 aBucket[sMapping(T29, l0, l4, l5)]++;

  82.                 aBucket[sMapping(T31, l0, l1, l6)]++;
  83.                 aBucket[sMapping(T37, l0, l2, l6)]++;
  84.                 aBucket[sMapping(T41, l0, l3, l6)]++;
  85.                 aBucket[sMapping(T43, l0, l4, l6)]++;
  86.                 aBucket[sMapping(T47, l0, l5, l6)]++;

  87.                 aBucket[sMapping(T53, l0, l1, l7)]++;
  88.                 aBucket[sMapping(T59, l0, l2, l7)]++;
  89.                 aBucket[sMapping(T61, l0, l3, l7)]++;
  90.                 aBucket[sMapping(T67, l0, l4, l7)]++;
  91.                 aBucket[sMapping(T71, l0, l5, l7)]++;
  92.                 aBucket[sMapping(T73, l0, l6, l7)]++;
  93.             }
  94.             l7 = l6;
  95.             l6 = l5;
  96.             l5 = l4;
  97.             l4 = l3;
  98.             l3 = l2;
  99.             l2 = l1;
  100.             l1 = l0;
  101.         }
  102.         lag = l7 << 48 | l6 << 40 | l5 << 32 | l4 << 24 | l3 << 16 | l2 << 8 | l1;
  103.     }

  104.     @Override
  105.     protected int[] getLag() {
  106.         return new int[] {(int) (lag & 0xFF), (int) (lag >>> 8 & 0xFF), (int) (lag >>> 16 & 0xFF),
  107.                 (int) (lag >>> 24 & 0xFF), (int) (lag >>> 32 & 0xFF), (int) (lag >>> 40 & 0xFF),
  108.                 (int) (lag >>> 48 & 0xFF)};
  109.     }
  110. }