1*49fe348cSAndroid Build Coastguard Worker# 2*49fe348cSAndroid Build Coastguard Worker# Copyright 2022 Google LLC 3*49fe348cSAndroid Build Coastguard Worker# 4*49fe348cSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*49fe348cSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*49fe348cSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*49fe348cSAndroid Build Coastguard Worker# 8*49fe348cSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*49fe348cSAndroid Build Coastguard Worker# 10*49fe348cSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*49fe348cSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 12*49fe348cSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*49fe348cSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*49fe348cSAndroid Build Coastguard Worker# limitations under the License. 15*49fe348cSAndroid Build Coastguard Worker# 16*49fe348cSAndroid Build Coastguard Worker 17*49fe348cSAndroid Build Coastguard Workerimport numpy as np 18*49fe348cSAndroid Build Coastguard Worker 19*49fe348cSAndroid Build Coastguard Workerimport lc3 20*49fe348cSAndroid Build Coastguard Workerimport tables as T, appendix_c as C 21*49fe348cSAndroid Build Coastguard Worker 22*49fe348cSAndroid Build Coastguard Worker 23*49fe348cSAndroid Build Coastguard Worker### ------------------------------------------------------------------------ ### 24*49fe348cSAndroid Build Coastguard Worker 25*49fe348cSAndroid Build Coastguard Workerclass AttackDetector: 26*49fe348cSAndroid Build Coastguard Worker 27*49fe348cSAndroid Build Coastguard Worker def __init__(self, dt, sr): 28*49fe348cSAndroid Build Coastguard Worker 29*49fe348cSAndroid Build Coastguard Worker self.dt = dt 30*49fe348cSAndroid Build Coastguard Worker self.sr = sr 31*49fe348cSAndroid Build Coastguard Worker self.ms = T.DT_MS[dt] 32*49fe348cSAndroid Build Coastguard Worker 33*49fe348cSAndroid Build Coastguard Worker self.xn1 = 0 34*49fe348cSAndroid Build Coastguard Worker self.xn2 = 0 35*49fe348cSAndroid Build Coastguard Worker self.en1 = 0 36*49fe348cSAndroid Build Coastguard Worker self.an1 = 0 37*49fe348cSAndroid Build Coastguard Worker self.p_att = 0 38*49fe348cSAndroid Build Coastguard Worker 39*49fe348cSAndroid Build Coastguard Worker def is_enabled(self, nbytes): 40*49fe348cSAndroid Build Coastguard Worker 41*49fe348cSAndroid Build Coastguard Worker c1 = self.dt == T.DT_10M and \ 42*49fe348cSAndroid Build Coastguard Worker self.sr == T.SRATE_32K and nbytes > 80 43*49fe348cSAndroid Build Coastguard Worker 44*49fe348cSAndroid Build Coastguard Worker c2 = self.dt == T.DT_10M and \ 45*49fe348cSAndroid Build Coastguard Worker self.sr >= T.SRATE_48K and nbytes >= 100 46*49fe348cSAndroid Build Coastguard Worker 47*49fe348cSAndroid Build Coastguard Worker c3 = self.dt == T.DT_7M5 and \ 48*49fe348cSAndroid Build Coastguard Worker self.sr == T.SRATE_32K and nbytes >= 61 and nbytes < 150 49*49fe348cSAndroid Build Coastguard Worker 50*49fe348cSAndroid Build Coastguard Worker c4 = self.dt == T.DT_7M5 and \ 51*49fe348cSAndroid Build Coastguard Worker self.sr >= T.SRATE_48K and nbytes >= 75 and nbytes < 150 52*49fe348cSAndroid Build Coastguard Worker 53*49fe348cSAndroid Build Coastguard Worker return c1 or c2 or c3 or c4 54*49fe348cSAndroid Build Coastguard Worker 55*49fe348cSAndroid Build Coastguard Worker def run(self, nbytes, x): 56*49fe348cSAndroid Build Coastguard Worker 57*49fe348cSAndroid Build Coastguard Worker ### Downsampling and filtering input 58*49fe348cSAndroid Build Coastguard Worker 59*49fe348cSAndroid Build Coastguard Worker mf = int(16 * self.ms) 60*49fe348cSAndroid Build Coastguard Worker 61*49fe348cSAndroid Build Coastguard Worker r = len(x) // mf 62*49fe348cSAndroid Build Coastguard Worker x_att = np.array([ np.sum(x[i*r:(i+1)*r]) for i in range(mf) ]) 63*49fe348cSAndroid Build Coastguard Worker 64*49fe348cSAndroid Build Coastguard Worker x_hp = np.empty(mf) 65*49fe348cSAndroid Build Coastguard Worker x_hp[0 ] = 0.375 * x_att[0 ] - 0.5 * self.xn1 + 0.125 * self.xn2 66*49fe348cSAndroid Build Coastguard Worker x_hp[1 ] = 0.375 * x_att[1 ] - 0.5 * x_att[0 ] + 0.125 * self.xn1 67*49fe348cSAndroid Build Coastguard Worker x_hp[2:] = 0.375 * x_att[2:] - 0.5 * x_att[1:-1] + 0.125 * x_att[0:-2] 68*49fe348cSAndroid Build Coastguard Worker self.xn2 = x_att[-2] 69*49fe348cSAndroid Build Coastguard Worker self.xn1 = x_att[-1] 70*49fe348cSAndroid Build Coastguard Worker 71*49fe348cSAndroid Build Coastguard Worker ### Energy calculation 72*49fe348cSAndroid Build Coastguard Worker 73*49fe348cSAndroid Build Coastguard Worker nb = int(self.ms / 2.5) 74*49fe348cSAndroid Build Coastguard Worker 75*49fe348cSAndroid Build Coastguard Worker e_att = np.array([ np.sum(np.square(x_hp[40*i:40*(i+1)])) 76*49fe348cSAndroid Build Coastguard Worker for i in range(nb) ]) 77*49fe348cSAndroid Build Coastguard Worker 78*49fe348cSAndroid Build Coastguard Worker a_att = np.empty(nb) 79*49fe348cSAndroid Build Coastguard Worker a_att[0] = np.maximum(0.25 * self.an1, self.en1) 80*49fe348cSAndroid Build Coastguard Worker for i in range(1,nb): 81*49fe348cSAndroid Build Coastguard Worker a_att[i] = np.maximum(0.25 * a_att[i-1], e_att[i-1]) 82*49fe348cSAndroid Build Coastguard Worker self.en1 = e_att[-1] 83*49fe348cSAndroid Build Coastguard Worker self.an1 = a_att[-1] 84*49fe348cSAndroid Build Coastguard Worker 85*49fe348cSAndroid Build Coastguard Worker ### Attack Detection 86*49fe348cSAndroid Build Coastguard Worker 87*49fe348cSAndroid Build Coastguard Worker p_att = -1 88*49fe348cSAndroid Build Coastguard Worker flags = [ (e_att[i] > 8.5 * a_att[i]) for i in range(nb) ] 89*49fe348cSAndroid Build Coastguard Worker 90*49fe348cSAndroid Build Coastguard Worker for (i, f) in enumerate(flags): 91*49fe348cSAndroid Build Coastguard Worker if f: p_att = i 92*49fe348cSAndroid Build Coastguard Worker 93*49fe348cSAndroid Build Coastguard Worker f_att = p_att >= 0 or self.p_att - 1 >= nb // 2 94*49fe348cSAndroid Build Coastguard Worker self.p_att = 1 + p_att 95*49fe348cSAndroid Build Coastguard Worker 96*49fe348cSAndroid Build Coastguard Worker return self.is_enabled(nbytes) and f_att 97*49fe348cSAndroid Build Coastguard Worker 98*49fe348cSAndroid Build Coastguard Worker 99*49fe348cSAndroid Build Coastguard Workerdef initial_state(): 100*49fe348cSAndroid Build Coastguard Worker return { 'en1': 0.0, 'an1': 0.0, 'p_att': 0 } 101*49fe348cSAndroid Build Coastguard Worker 102*49fe348cSAndroid Build Coastguard Worker### ------------------------------------------------------------------------ ### 103*49fe348cSAndroid Build Coastguard Worker 104*49fe348cSAndroid Build Coastguard Workerdef check_enabling(rng, dt): 105*49fe348cSAndroid Build Coastguard Worker 106*49fe348cSAndroid Build Coastguard Worker ok = True 107*49fe348cSAndroid Build Coastguard Worker 108*49fe348cSAndroid Build Coastguard Worker for sr in range(T.SRATE_8K, T.SRATE_48K + 1): 109*49fe348cSAndroid Build Coastguard Worker 110*49fe348cSAndroid Build Coastguard Worker attdet = AttackDetector(dt, sr) 111*49fe348cSAndroid Build Coastguard Worker 112*49fe348cSAndroid Build Coastguard Worker for nbytes in [ 61, 61-1, 75-1, 75, 80, 80+1, 100-1, 100, 150-1, 150 ]: 113*49fe348cSAndroid Build Coastguard Worker 114*49fe348cSAndroid Build Coastguard Worker f_att = lc3.attdet_run(dt, sr, nbytes, 115*49fe348cSAndroid Build Coastguard Worker initial_state(), 2 * rng.random(T.NS[dt][sr]+6) - 1) 116*49fe348cSAndroid Build Coastguard Worker 117*49fe348cSAndroid Build Coastguard Worker ok = ok and f_att == attdet.is_enabled(nbytes) 118*49fe348cSAndroid Build Coastguard Worker 119*49fe348cSAndroid Build Coastguard Worker return ok 120*49fe348cSAndroid Build Coastguard Worker 121*49fe348cSAndroid Build Coastguard Workerdef check_unit(rng, dt, sr): 122*49fe348cSAndroid Build Coastguard Worker 123*49fe348cSAndroid Build Coastguard Worker ns = T.NS[dt][sr] 124*49fe348cSAndroid Build Coastguard Worker ok = True 125*49fe348cSAndroid Build Coastguard Worker 126*49fe348cSAndroid Build Coastguard Worker attdet = AttackDetector(dt, sr) 127*49fe348cSAndroid Build Coastguard Worker 128*49fe348cSAndroid Build Coastguard Worker state_c = initial_state() 129*49fe348cSAndroid Build Coastguard Worker x_c = np.zeros(ns+6) 130*49fe348cSAndroid Build Coastguard Worker 131*49fe348cSAndroid Build Coastguard Worker for run in range(100): 132*49fe348cSAndroid Build Coastguard Worker 133*49fe348cSAndroid Build Coastguard Worker ### Generate noise, and an attack at random point 134*49fe348cSAndroid Build Coastguard Worker 135*49fe348cSAndroid Build Coastguard Worker x = ((2 * rng.random(ns)) - 1) * (2 ** 8 - 1) 136*49fe348cSAndroid Build Coastguard Worker x[(ns * rng.random()).astype(int)] *= 2 ** 7 137*49fe348cSAndroid Build Coastguard Worker 138*49fe348cSAndroid Build Coastguard Worker ### Check Implementation 139*49fe348cSAndroid Build Coastguard Worker 140*49fe348cSAndroid Build Coastguard Worker f_att = attdet.run(100, x) 141*49fe348cSAndroid Build Coastguard Worker 142*49fe348cSAndroid Build Coastguard Worker x_c = np.append(x_c[-6:], x) 143*49fe348cSAndroid Build Coastguard Worker f_att_c = lc3.attdet_run(dt, sr, 100, state_c, x_c) 144*49fe348cSAndroid Build Coastguard Worker 145*49fe348cSAndroid Build Coastguard Worker ok = ok and f_att_c == f_att 146*49fe348cSAndroid Build Coastguard Worker ok = ok and np.amax(np.abs(1 - state_c['en1']/attdet.en1)) < 2 147*49fe348cSAndroid Build Coastguard Worker ok = ok and np.amax(np.abs(1 - state_c['an1']/attdet.an1)) < 2 148*49fe348cSAndroid Build Coastguard Worker ok = ok and state_c['p_att'] == attdet.p_att 149*49fe348cSAndroid Build Coastguard Worker 150*49fe348cSAndroid Build Coastguard Worker return ok 151*49fe348cSAndroid Build Coastguard Worker 152*49fe348cSAndroid Build Coastguard Workerdef check_appendix_c(dt): 153*49fe348cSAndroid Build Coastguard Worker 154*49fe348cSAndroid Build Coastguard Worker i0 = dt - T.DT_7M5 155*49fe348cSAndroid Build Coastguard Worker sr = T.SRATE_48K 156*49fe348cSAndroid Build Coastguard Worker 157*49fe348cSAndroid Build Coastguard Worker ok = True 158*49fe348cSAndroid Build Coastguard Worker state = initial_state() 159*49fe348cSAndroid Build Coastguard Worker 160*49fe348cSAndroid Build Coastguard Worker x = np.append(np.zeros(6), C.X_PCM_ATT[i0][0]) 161*49fe348cSAndroid Build Coastguard Worker f_att = lc3.attdet_run(dt, sr, C.NBYTES_ATT[i0], state, x) 162*49fe348cSAndroid Build Coastguard Worker ok = ok and f_att == C.F_ATT[i0][0] 163*49fe348cSAndroid Build Coastguard Worker 164*49fe348cSAndroid Build Coastguard Worker x = np.append(x[-6:], C.X_PCM_ATT[i0][1]) 165*49fe348cSAndroid Build Coastguard Worker f_att = lc3.attdet_run(dt, sr, C.NBYTES_ATT[i0], state, x) 166*49fe348cSAndroid Build Coastguard Worker ok = ok and f_att == C.F_ATT[i0][1] 167*49fe348cSAndroid Build Coastguard Worker 168*49fe348cSAndroid Build Coastguard Worker return ok 169*49fe348cSAndroid Build Coastguard Worker 170*49fe348cSAndroid Build Coastguard Workerdef check(): 171*49fe348cSAndroid Build Coastguard Worker 172*49fe348cSAndroid Build Coastguard Worker rng = np.random.default_rng(1234) 173*49fe348cSAndroid Build Coastguard Worker ok = True 174*49fe348cSAndroid Build Coastguard Worker 175*49fe348cSAndroid Build Coastguard Worker for dt in range(T.NUM_DT): 176*49fe348cSAndroid Build Coastguard Worker ok and check_enabling(rng, dt) 177*49fe348cSAndroid Build Coastguard Worker 178*49fe348cSAndroid Build Coastguard Worker for dt in ( T.DT_7M5, T.DT_10M ): 179*49fe348cSAndroid Build Coastguard Worker for sr in ( T.SRATE_32K, T.SRATE_48K ): 180*49fe348cSAndroid Build Coastguard Worker ok = ok and check_unit(rng, dt, sr) 181*49fe348cSAndroid Build Coastguard Worker 182*49fe348cSAndroid Build Coastguard Worker for dt in ( T.DT_7M5, T.DT_10M ): 183*49fe348cSAndroid Build Coastguard Worker ok = ok and check_appendix_c(dt) 184*49fe348cSAndroid Build Coastguard Worker 185*49fe348cSAndroid Build Coastguard Worker return ok 186*49fe348cSAndroid Build Coastguard Worker 187*49fe348cSAndroid Build Coastguard Worker### ------------------------------------------------------------------------ ### 188